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);
63 resultfn = fullfile(filecache_path,...
64 [funcname,keystr,'.mat
']);
65 multval_cache = fullfile(filecache_path,...
70 funcstr = strtrim(evalc('disp(funcptr)
'));
72 if exist(resultfn,'file
');
73 loaded = load(resultfn);
75 elseif exist(multval_cache,'file
')
76 tmp = load(multval_cache);
77 tmp_key_pos = find(tmp.keylist==key,1);
78 if ~isempty(tmp_key_pos)
79 tmp_key_ind = tmp.map_key2ind(tmp_key_pos);
80 tmp_file_ind = tmp.map_key2file(tmp_key_pos);
81 storefile = fullfile(filecache_path,...
82 [funcname,'mv
',num2str(tmp_file_ind),'.mat
']);
83 if exist(storefile,'file
')
84 tmp = load(storefile);
85 loaded = tmp.cache(tmp_key_ind);
88 error(['Could not find file
',storefile,...
89 ', which is specified in multivalue cache list.
']);
95 % isequal does not work for handles
96 % if isequal(tmp.saveargs,saveargs)
97 if isequal_ignore_handles(loaded.saveargs,saveargs)
98 varargout = loaded.varargout;
100 disp(['call of
',funcstr,', successfully read from cache, key=
',keystr]);
103 % the key-computation formula must be updated in this case...
104 disp(['arguments in cached file and current call
do not
',...
106 disp('please change key-
function in file_cache_function!
');
107 disp('recomputation is started and cache-file replaced.
');
115 disp('result not found in cache
');
116 [varargout{1:nargout}] = funcptr(varargin{:});
117 % save(resultfn,'varargin
');
119 siz=whos('varargout
');
120 % if size is less than 100kb, store in multi-value cache.
121 if(siz.bytes < 1024*100)
122 if exist(multval_cache,'file
')
123 meta=load(multval_cache);
124 max_file_ind = meta.map_key2file(end);
125 max_key_ind = meta.map_key2ind(end)+1;
126 last_size = meta.last_size;
127 % if store file size exceeds 10MB, create a new one
128 if (last_size + siz.bytes > 1024*10000)
129 max_file_ind = max_file_ind + 1;
134 meta.map_key2file = [];
135 meta.map_key2ind = [];
139 storefile = fullfile(filecache_path,...
140 [funcname,'mv
',num2str(max_file_ind),'.mat
']);
141 if exist(storefile, 'file
')
144 cache(max_key_ind).saveargs = saveargs;
145 cache(max_key_ind).varargout = varargout;
147 tmp_size = whos('cache
');
148 last_size = tmp_size.bytes;
149 keylist = [meta.keylist, key];
150 map_key2file = [meta.map_key2file, max_file_ind];
151 map_key2ind = [meta.map_key2ind, max_key_ind];
153 save(multval_cache, 'last_size
', 'keylist
', 'map_key2file
', 'map_key2ind
');
154 save(storefile, 'cache
');
157 save(resultfn,'saveargs
','varargout
');
159 disp(['call of
',funcstr,', now computed and cached, key=
',keystr]);