rbmatlab  1.13.10
 All Classes Namespaces Files Functions Variables Groups Pages
CacheableObject.m
1 classdef CacheableObject < handle
2  % class which wraps an object pointer to an object that is stored somewhere
3  % on the hdd (in a cache)
4  %
5  % As the wrapped object is already stored somewhere, it is not stored if the
6  % CacheableObject is stored. Instead only the filename and some consistency
7  % hash are stored on the hdd, from which the wrapped object can be reliably
8  % restored. (with a consistency check on the data)
9  %
10 
11  properties
12  % the file name where the wrapped object is stored
13  matfile;
14 
15  % a hash computed from the cache file
16  md5;
17 
18  % the pointer to the wrapped object
19  obj;
20 
21  % the full path to the file where the wrapped object is stored
22  matfile_path;
23  end
24 
25  methods
26  function co = CacheableObject(matfile, fieldname)
27  % function co = CacheableObject(matfile, fieldname)
28  % constructor
29  %
30  % At construction time, the #obj attribute is tried to be filled with the
31  % obj stored in 'matfile'.
32  %
33  % Parameters:
34  % matfile: a string specifying the full path or only the file name of
35  % the mat-file where the object is stored.
36  % fieldname: a string specifying a fieldname that shall be passed as
37  % second argument to the load method. (@default = [])
38 
39  if nargin == 0
40  matfile = evalin('base', 'matfile');
41  end
42  if exist(matfile, 'file') || exist([matfile, '.mat'], 'file')
43  matp = matfile;
44  [dummy, matfile, ext] = fileparts(matfile);
45  else
46  matp = fullfile(rbmatlabresult, matfile);
47  end
48  if ~exist(matp, 'file') && ~exist([matp, '.mat'], 'file')
49  matp = fullfile(rbmatlabresult, '..', matfile);
50  if ~exist(matp, 'file') && ~exist([matp, '.mat'], 'file')
51  [st, matp] = system(['find ', fullfile(rbmatlabresult, '..', '..'), ' -iname ''', matfile, '*'' | head -1']);
52  if ~exist(matp, 'file')
53  error(['could not load file: ', matfile]);
54  end
55  end
56  end
57  if ~exist(matp, 'file')
58  matfile = [matfile, '.mat'];
59  matp = [matp, '.mat'];
60  end
61  co.matfile = matfile;
62  co.matfile_path = matp;
63  co.md5 = CacheableObject.compute_hash(matp);
64  if nargin >= 2 && ~isempty(fieldname)
65  co.obj = load(matp, fieldname);
66  else
67  co.obj = load(matp);
68  end
69  end
70 
71 
72  function obj = saveobj(this)
73  % function obj = saveobj(this)
74  % saves all fields except for the #obj handle
75  %
76  % Return values:
77  % obj: struct to be stored in file
78  obj.matfile_path = this.matfile_path;
79  obj.matfile = this.matfile;
80  obj.md5 = this.md5;
81  end
82 
83  end
84 
85  methods(Static = true)
86  function this = loadobj(obj)
87  % function this = loadobj(obj)
88  % restores the CacheableObject object and fills the #obj handle again.
89  this = CacheableObject(obj.matfile_path);
90 
91  if ~isequal(obj.md5, this.md5)
92  this = [];
93  error('RBMatlab:CacheableObject:Consistency', 'Consistency check failed! The stored object has changed!');
94  end
95  end
96  end
97 
98  methods(Static=true, Access=private)
99  function md5 = compute_hash(matpath)
100  fid=fopen(matpath, 'r');
101  md5='';
102  while ~feof(fid)
103  tmp=fread(fid, 1e5);
104  md5 = hash([tmp; uint8(md5)'], 'md5');
105  end
106  fclose(fid);
107  end
108  end
109 end