3 %
function used
for file-caching other
function calls.
5 % If an expensive
function
8 % [E, F] = myfunction(A,B,C)
11 % is called frequently during a program run, a filecaching can be
12 % used, i.e. one calls the
function instead as
18 % If the
function result exists in the cache,
this is loaded, otherwise the
19 %
function is called, the result saved in the cache and the result returned.
22 % funcptr: is the pointer to a
function whose calls are to be cached.
23 % varargin: is parameter list of the cached
function call
26 % varargout:
return values of the cached
function call
28 % - The cache-directory is assumed to be in 'RBMATLABTEMP/cache'
29 % - The cache-directory can be cleared with the function filecache_clear()
31 % Bernard Haasdonk 22.5.2007
34 error('filecaching only works for functions with return values!');
37 funcname = func2str(funcptr);
39 % determining of a
'hash-code' from the
function-arguments:
40 tmpfn = fullfile(filecache_path,'tmparg.mat');
42 for i=1:length(saveargs)
43 if isobject(varargin{i})
44 warning(
'off',
'MATLAB:structOnObject');
45 saveargs{i} =
struct(varargin{i});
46 warning(
'on',
'MATLAB:structOnObject');
50 save(tmpfn,
'saveargs');
51 fid = fopen(tmpfn,
'r');
53 % cut of header, which contains date, i.e. first 116 bytes
56 uintbin = uint32(bin);
57 % simple arithmetics
for identifying arguments
58 key = mod(sum(uintbin.*uint32(1:length(uintbin))
'),1e9);
59 keystr = num2str(key);
61 resultfn = fullfile(filecache_path,...
62 [funcname,keystr,'.mat
']);
63 multval_cache = fullfile(filecache_path,...
68 funcstr = strtrim(evalc('disp(funcptr)
'));
70 if exist(resultfn,'file
');
71 loaded = load(resultfn);
73 elseif exist(multval_cache,'file
')
74 tmp = load(multval_cache);
75 tmp_key_pos = find(tmp.keylist==key,1);
76 if ~isempty(tmp_key_pos)
77 tmp_key_ind = tmp.map_key2ind(tmp_key_pos);
78 tmp_file_ind = tmp.map_key2file(tmp_key_pos);
79 storefile = fullfile(filecache_path,...
80 [funcname,'mv
',num2str(tmp_file_ind),'.mat
']);
81 if exist(storefile,'file
')
82 tmp = load(storefile);
83 loaded = tmp.cache(tmp_key_ind);
86 error(['Could not find file
',storefile,...
87 ', which is specified in multivalue cache list.
']);
93 % isequal does not work for handles
94 % if isequal(tmp.saveargs,saveargs)
95 if isequal(loaded.saveargs,saveargs)
96 varargout = loaded.varargout;
98 debugdisp(['call of
',funcstr,', successfully read from cache, key=
',keystr]);
100 % the key-computation formula must be updated in this case...
101 debugdisp(['arguments in cached file and current call
do not
',...
103 debugdisp('please change key-
function in file_cache_function!
');
104 debugdisp('recomputation is started and cache-file replaced.
');
111 debugdisp('result not found in cache
');
112 [varargout{1:nargout(funcptr)}] = funcptr(varargin{:});
114 siz=whos('varargout
');
115 % if size is less than 100kb, store in multi-value cache.
116 if(siz.bytes < 1024*100)
117 if exist(multval_cache,'file
')
118 meta=load(multval_cache);
119 max_file_ind = meta.map_key2file(end);
120 max_key_ind = meta.map_key2ind(end)+1;
121 last_size = meta.last_size;
122 % if store file size exceeds 10MB, create a new one
123 if (last_size + siz.bytes > 1024*10000)
124 max_file_ind = max_file_ind + 1;
129 meta.map_key2file = [];
130 meta.map_key2ind = [];
134 storefile = fullfile(filecache_path,...
135 [funcname,'mv
',num2str(max_file_ind),'.mat
']);
136 if exist(storefile, 'file
')
139 cache(max_key_ind).saveargs = saveargs;
140 cache(max_key_ind).varargout = varargout;
142 tmp_size = whos('cache
');
143 last_size = tmp_size.bytes;
144 keylist = [meta.keylist, key];
145 map_key2file = [meta.map_key2file, max_file_ind];
146 map_key2ind = [meta.map_key2ind, max_key_ind];
148 save(multval_cache, 'last_size
', 'keylist
', 'map_key2file
', 'map_key2ind
');
149 save(storefile, 'cache
');
152 save(resultfn,'saveargs
','varargout
');
154 debugdisp(['call of
',funcstr,', now computed and cached, key=
',keystr]);
157 % Append the flag that indicates whether the result was cached or not
158 if nargout == length(varargout)+1
159 varargout{length(varargout)+1} = is_cached;
function varargout = filecache_function(funcptr, varargin)
function used for file-caching other function calls.