eidors_cache

PURPOSE ^

EIDORS_CACHE Control eidors caching

SYNOPSIS ^

function varargout=eidors_cache( command, varargin )

DESCRIPTION ^

 EIDORS_CACHE Control eidors caching
 Usage: eidors_cache( command, limit ) for cache management
 Usage: eidors_cache(@function_handle, {params1, ... }) for shorthand
        chashing in m-files

 USAGE:
   eidors_cache( 'clear_all' ) 
   eidors_cache  clear

   eidors_cache( 'list' )
   eidors_cache( 'show_objs' )
       - list all objects
   eidors_cache(___, order)
       - sort by specific order. Valid values are 
         {time}, size, effort, count, rank

   eidors_cache( 'clear_old'. timestamp );
   eidors_cache( 'clear_new', timestamp );
      - clear all variables older (or newer) than timestamp
      - example:
         time_now= now;
         lots_of_eidors_calcs % don't need to cache this stuff
         eidors_cache('clear_new',time_now);

   eidors_cache( 'clear_max', memory_in_bytes );
      - clear cache so it has less than memory_in_bytes

   eidors_cache( 'cache_size', memory_in_bytes );
      - set max cache size to be memory_in_bytes
      - without 2nd arg will return current cache_size

   eidors_cache( 'clear_name', cache_name )
      - eg. eidors_cache( 'clear_name', 'inv_solve_diff_GN_one_step')
      - clear all variables with name 

   eidors_cache( 'clear_model_library' );
      - clear the eidors model library directory
      - NOTE: this function is experimental. 
      - TODO: add a way to specify what to clear
  
   eidors_cache( 'boost_priority', value)
      - modify the priority of the next cached items
      - low priority variables will be deleted first when memory is tight

   eidors_cache( 'off' )
   eidors_cache( 'disable' )
   eidors_cache( 'off', 'function_name' )
      - new values are not added to cache
      - requests for cached values return []
      - if specified, only applies to a specific function

   eidors_cache( 'on' )
   eidors_cache( 'enable' )
   eidors_cache( 'on', 'function_name' )
      - re-enables caching
      - if specified, only applies to a specific function

   eidors_cache( 'status' )
      - queries the caching status
      - 0  : all off
      - 1  : all on
      - 0.5: off for some functions

   eidors_cache( 'debug_on' )
   eidors_cache( 'debug_on', 'function_name' )
      - enables debug output
      - if specified, only applies to a specific function
      - will print a message everytime an object is removed from cache

   eidors_cache( 'debug_off' )
   eidors_cache( 'debug_off', 'function_name' );
      - disables debug output
      - if specified, only applies to a specific function

   eidors_cache( 'debug_status' )
      - queries debug status
      - output analogous to cache status above

   v1 = eidors_cache( @function_handle, {param1, param2, ...})
   [v1, v2, ...] = eidors_cache( @function_handle, {param1, param2, ...})
   [v1, v2, ...] = eidors_cache( ... , opt)
      Shorthand interface for caching the output of a specific function.
      Specify all arguments to the function as a cell array. They will all
      be used for as a caching object by default. The following options
      are available:
        opt.cache_obj
            - a single value, or a cell array of values to cache on, 
              rather than all the inputs (e.g. not all values of an input
              struct may be used in the function)
        opt.boost_priority
            - priority boost to use for that function
        opt.fstr
            - name to use for the cached result
        opt.log_level
            - message level to use with eidors_msg. By default, it's 4 for
              'setting cache' and 3 for 'using cached value'
        opt.cache_to_disk = true or '.'  
        opt.cache_to_disk = 'path/to/cache/dir'
            - Save the cached file to disk and reload it when called
            - The file is named 'eidors_cache_id????.mat' or opt.fstr,'_id???'

   eidors_cache( 'cache_path' )
   eidors_cache( 'cache_path', '/path/to/cache/path' )
       - get and set cache_path, a path to a writable
           directory in which eidors can store files

   eidors_cache( 'eidors_path' )
   eidors_cache( 'eidors_path', '/path/to/eidors/' )
       - /path/to/eidors is the path in which eidors_startup.m is found

 See also EIDORS_OBJ

CROSS-REFERENCE INFORMATION ^

This function calls: This function is called by:

SUBFUNCTIONS ^

SOURCE CODE ^

0001 function varargout=eidors_cache( command, varargin )
0002 % EIDORS_CACHE Control eidors caching
0003 % Usage: eidors_cache( command, limit ) for cache management
0004 % Usage: eidors_cache(@function_handle, {params1, ... }) for shorthand
0005 %        chashing in m-files
0006 %
0007 % USAGE:
0008 %   eidors_cache( 'clear_all' )
0009 %   eidors_cache  clear
0010 %
0011 %   eidors_cache( 'list' )
0012 %   eidors_cache( 'show_objs' )
0013 %       - list all objects
0014 %   eidors_cache(___, order)
0015 %       - sort by specific order. Valid values are
0016 %         {time}, size, effort, count, rank
0017 %
0018 %   eidors_cache( 'clear_old'. timestamp );
0019 %   eidors_cache( 'clear_new', timestamp );
0020 %      - clear all variables older (or newer) than timestamp
0021 %      - example:
0022 %         time_now= now;
0023 %         lots_of_eidors_calcs % don't need to cache this stuff
0024 %         eidors_cache('clear_new',time_now);
0025 %
0026 %   eidors_cache( 'clear_max', memory_in_bytes );
0027 %      - clear cache so it has less than memory_in_bytes
0028 %
0029 %   eidors_cache( 'cache_size', memory_in_bytes );
0030 %      - set max cache size to be memory_in_bytes
0031 %      - without 2nd arg will return current cache_size
0032 %
0033 %   eidors_cache( 'clear_name', cache_name )
0034 %      - eg. eidors_cache( 'clear_name', 'inv_solve_diff_GN_one_step')
0035 %      - clear all variables with name
0036 %
0037 %   eidors_cache( 'clear_model_library' );
0038 %      - clear the eidors model library directory
0039 %      - NOTE: this function is experimental.
0040 %      - TODO: add a way to specify what to clear
0041 %
0042 %   eidors_cache( 'boost_priority', value)
0043 %      - modify the priority of the next cached items
0044 %      - low priority variables will be deleted first when memory is tight
0045 %
0046 %   eidors_cache( 'off' )
0047 %   eidors_cache( 'disable' )
0048 %   eidors_cache( 'off', 'function_name' )
0049 %      - new values are not added to cache
0050 %      - requests for cached values return []
0051 %      - if specified, only applies to a specific function
0052 %
0053 %   eidors_cache( 'on' )
0054 %   eidors_cache( 'enable' )
0055 %   eidors_cache( 'on', 'function_name' )
0056 %      - re-enables caching
0057 %      - if specified, only applies to a specific function
0058 %
0059 %   eidors_cache( 'status' )
0060 %      - queries the caching status
0061 %      - 0  : all off
0062 %      - 1  : all on
0063 %      - 0.5: off for some functions
0064 %
0065 %   eidors_cache( 'debug_on' )
0066 %   eidors_cache( 'debug_on', 'function_name' )
0067 %      - enables debug output
0068 %      - if specified, only applies to a specific function
0069 %      - will print a message everytime an object is removed from cache
0070 %
0071 %   eidors_cache( 'debug_off' )
0072 %   eidors_cache( 'debug_off', 'function_name' );
0073 %      - disables debug output
0074 %      - if specified, only applies to a specific function
0075 %
0076 %   eidors_cache( 'debug_status' )
0077 %      - queries debug status
0078 %      - output analogous to cache status above
0079 %
0080 %   v1 = eidors_cache( @function_handle, {param1, param2, ...})
0081 %   [v1, v2, ...] = eidors_cache( @function_handle, {param1, param2, ...})
0082 %   [v1, v2, ...] = eidors_cache( ... , opt)
0083 %      Shorthand interface for caching the output of a specific function.
0084 %      Specify all arguments to the function as a cell array. They will all
0085 %      be used for as a caching object by default. The following options
0086 %      are available:
0087 %        opt.cache_obj
0088 %            - a single value, or a cell array of values to cache on,
0089 %              rather than all the inputs (e.g. not all values of an input
0090 %              struct may be used in the function)
0091 %        opt.boost_priority
0092 %            - priority boost to use for that function
0093 %        opt.fstr
0094 %            - name to use for the cached result
0095 %        opt.log_level
0096 %            - message level to use with eidors_msg. By default, it's 4 for
0097 %              'setting cache' and 3 for 'using cached value'
0098 %        opt.cache_to_disk = true or '.'
0099 %        opt.cache_to_disk = 'path/to/cache/dir'
0100 %            - Save the cached file to disk and reload it when called
0101 %            - The file is named 'eidors_cache_id????.mat' or opt.fstr,'_id???'
0102 %
0103 %   eidors_cache( 'cache_path' )
0104 %   eidors_cache( 'cache_path', '/path/to/cache/path' )
0105 %       - get and set cache_path, a path to a writable
0106 %           directory in which eidors can store files
0107 %
0108 %   eidors_cache( 'eidors_path' )
0109 %   eidors_cache( 'eidors_path', '/path/to/eidors/' )
0110 %       - /path/to/eidors is the path in which eidors_startup.m is found
0111 %
0112 % See also EIDORS_OBJ
0113 
0114 % (C) 2005-2013 Andy Adler and Bartlomiej Grychtol.
0115 % License: GPL version 2
0116 % $Id: eidors_cache.m 6002 2019-06-29 12:36:23Z aadler $
0117 
0118 % Comments
0119 % Want to clear specific structures
0120 %      to clear old variables
0121 %      to clear specific parts of structures
0122 
0123 if nargin==1 && ischar(command) && strcmp(command,'UNIT_TEST');
0124       do_unit_test; return; end
0125 
0126 global eidors_objects;
0127 if nargin<1
0128    fprintf('EIDORS_CACHE: current max memory = %.0f MB\n', ...
0129          eidors_objects.max_cache_size/(1024*1024)); 
0130    ww= whos('eidors_objects');
0131    fprintf('EIDORS_CACHE: cache memory used = %.0f MB\n', ...
0132          ww.bytes/(1024*1024)); 
0133    fprintf('EIDORS_CACHE: current priority = %d\n', ...
0134          eidors_objects.cache_priority); 
0135    return;
0136 elseif nargin > 1 
0137    limit = varargin{1};
0138 end
0139 
0140 
0141 % In order to do caching, we need to have an existing
0142 % function, as a string which exists as a function
0143 % handle.
0144 if isa(command, 'function_handle') || ...
0145   (ischar(command) && ...
0146    any(exist(command) == [2,3])) % m or mex-file
0147    % Test if we're being asked to cache on anonymous function
0148    %   and issue error
0149    if isa(command, 'function_handle')
0150       str = func2str(command);
0151       if str(1) == '@'
0152          error('Cannot cache anonymous functions');
0153       end
0154    end
0155    [varargout{1:nargout}] =  ...
0156            cache_shorthand(command, varargin{:});
0157    return
0158 end
0159 
0160     
0161 switch command
0162    case 'init'
0163       eidors_objects.cache_enable = 1;
0164       eidors_objects.cache_disabled_on = [];
0165       eidors_objects.cache_debug_enable = 0;
0166       eidors_objects.cache_debug_enabled_on = [];
0167       eidors_obj('cache_init');
0168       
0169    case 'clear_all'
0170       remove_objids
0171 
0172    case 'clear'
0173      switch nargin
0174        case 2
0175         eidors_cache('clear_name',limit);
0176        case 1
0177         eidors_cache('clear_all');
0178        otherwise
0179          error('Wrong number of inputs');
0180      end
0181       
0182    case 'cache_size'
0183       if nargin==2
0184       if ischar(limit); limit= str2num(limit); end
0185          eidors_objects.max_cache_size = limit;
0186       else
0187          varargout{1}= eidors_objects.max_cache_size;
0188       end
0189 
0190    case 'cache_path'
0191       if nargin == 1
0192          varargout{1}= eidors_objects.cache_path;
0193       else
0194          eidors_objects.cache_path = varargin{1};
0195       end
0196 
0197    case 'eidors_path'
0198       if nargin == 1
0199          varargout{1}= eidors_objects.eidors_path;
0200       else
0201          eidors_objects.eidors_path = varargin{1};
0202       end
0203    case {'disable' 'off'}
0204        if nargin == 1
0205            eidors_objects.cache_enable = 0;
0206            eidors_objects.cache_disabled_on = {};
0207        else
0208            eidors_objects.cache_enable = 0.5;
0209            if isfield(eidors_objects,'cache_disabled_on')
0210             if ~any(strcmp(eidors_objects.cache_disabled_on, limit))
0211                 eidors_objects.cache_disabled_on = [...
0212                     eidors_objects.cache_disabled_on; {limit}];
0213             end
0214            else
0215                eidors_objects.cache_disabled_on =  {limit};
0216            end
0217        end
0218    case {'enable' 'on'}
0219        if nargin == 1
0220            eidors_objects.cache_enable = 1;
0221            eidors_objects.cache_disabled_on = {};
0222        else
0223            if isfield(eidors_objects,'cache_disabled_on')
0224                idx = strcmp(eidors_objects.cache_disabled_on, limit);
0225                eidors_objects.cache_disabled_on(idx) = [];
0226            else 
0227                eidors_objects.cache_disabled_on = [];
0228            end
0229            if isempty(eidors_objects.cache_disabled_on)
0230                eidors_objects.cache_enable = 1;
0231            end
0232        end
0233    case 'status'
0234       if nargin == 1
0235          try
0236             varargout{1} = eidors_objects.cache_enable;
0237          catch
0238             varargout{1} = 1;
0239          end
0240       else
0241          if isfield(eidors_objects,'cache_disabled_on')
0242             idx = strcmp(eidors_objects.cache_disabled_on, limit);
0243             varargout{1} = double(~any(idx));
0244          end
0245       end
0246    case 'debug_status'
0247       if nargin == 1
0248          varargout{1} = eidors_objects.cache_debug_enable;
0249       else
0250          if isfield(eidors_objects,'cache_debug_enabled_on')
0251             idx = ismember(limit,eidors_objects.cache_debug_enabled_on);
0252             varargout{1} = idx | eidors_objects.cache_debug_enable==1;
0253          end
0254       end
0255    case 'debug_on'
0256        if nargin == 1
0257            eidors_objects.cache_debug_enable = 1;
0258            eidors_objects.cache_debug_enabled_on = {};
0259        else
0260            eidors_objects.cache_debug_enable = 0.5;
0261            if isfield(eidors_objects,'cache_debug_enabled_on')
0262             if ~any(strcmp(eidors_objects.cache_debug_enabled_on, limit))
0263                 eidors_objects.cache_debug_enabled_on = [...
0264                     eidors_objects.cache_debug_enabled_on; {limit}];
0265             end
0266            else
0267                eidors_objects.cache_debug_enabled_on =  {limit};
0268            end
0269        end
0270    case 'debug_off'
0271       if nargin == 1
0272          eidors_objects.cache_debug_enable = 0;
0273          eidors_objects.cache_debug_enabled_on = {};
0274       else
0275          if isfield(eidors_objects,'cache_debug_enabled_on')
0276             idx = strcmp(eidors_objects.cache_debug_enabled_on, limit);
0277             eidors_objects.cache_debug_enabled_on(idx) = [];
0278          else
0279             eidors_objects.cache_debug_enabled_on = [];
0280          end
0281          if isempty(eidors_objects.cache_debug_enabled_on)
0282             eidors_objects.cache_debug_enable = 0;
0283          end
0284       end
0285    case 'boost_priority'
0286       try
0287          varargout{1}= eidors_objects.cache_priority;
0288       catch
0289          varargout{1}= 0; % default priority
0290       end
0291       if nargin==2
0292       if ischar(limit); limit= str2double(limit); end
0293          varargout{1} = varargout{1} + limit;
0294       end
0295       eidors_objects.cache_priority = varargout{1};
0296 
0297    case {'list', 'show_objs'} 
0298       if nargin == 2 
0299          cache_list(limit);
0300       else
0301          cache_list;
0302       end
0303       
0304       
0305    case 'clear_max'
0306       if ischar(limit); limit= str2double(limit); end
0307       try
0308          c = eidors_objects.cache.cols;
0309       catch 
0310          return
0311       end
0312       
0313       priidx = get_cache_priority;
0314       [jnk, idx] = sort(priidx);
0315       tot=     cumsum([eidors_objects.cache.meta{idx,c.size}]); 
0316       rmidx  = idx(tot > limit);
0317       remove_objids( rmidx );
0318 
0319    case 'clear_old'
0320       if ischar(limit); limit= str2num(limit); end
0321       try
0322          c = eidors_objects.cache.cols;
0323       catch
0324          return
0325       end
0326       idx = find([eidors_objects.cache.meta{:,c.time}] < limit);
0327       remove_objids( idx );
0328 
0329    case 'clear_new'
0330       if ischar(limit); limit= str2num(limit); end
0331       try
0332          c = eidors_objects.cache.cols;
0333       catch
0334          return
0335       end
0336       idx = find([eidors_objects.cache.meta{:,c.time}] > limit);
0337       remove_objids( idx );
0338 
0339    case 'clear_model_library'
0340       %TODO: add ways to select what to delete
0341       delete([eidors_objects.model_cache,'/*.mat']);
0342 
0343    case 'clear_name'
0344       idx = clear_names_cache( limit );
0345       remove_objids( idx );
0346       
0347    case 'dump'
0348       varargout{1} = eidors_objects;
0349       
0350    case 'load'
0351       eidors_objects = limit;
0352       
0353    otherwise
0354       error('command %s not understood',command);
0355 end
0356 
0357 function cache_list (order)
0358    global eidors_objects;
0359    try
0360       meta = eidors_objects.cache.meta;
0361    catch
0362       return
0363    end
0364    if nargin == 0
0365        order = 'time';
0366    end
0367    
0368    c = eidors_objects.cache.cols;
0369    if isempty(meta)
0370       fprintf('No objects in cache\n');
0371       return
0372    end
0373    meta(:,c.time) = cellstr(datestr([meta{:,c.time}],'yyyy-mm-dd HH:MM:SS.FFF'));
0374    N = size(meta,2);
0375    %    [jnk, priidx] = sortrows(meta(:,[c.score_eff c.score_sz c.time]),[-1 2 -3]);
0376    
0377    meta(:,N+1) = num2cell(get_cache_priority);
0378    switch order
0379        case 'time'
0380            meta = mysortrows(meta,c.time); % sort by time
0381        case {'prop','name'}
0382            meta = mysortrows(meta,c.prop); % sort by name
0383        case 'rank'
0384            meta = mysortrows(meta,N+1); % sort by rank
0385        case 'size'
0386            meta = mysortrows(meta,-c.size); % sort by rank
0387        case 'effort'
0388            meta = mysortrows(meta,-c.effort);
0389        case 'count'
0390            meta = mysortrows(meta,-c.count);
0391        otherwise
0392            error('Unrecognized sort order');
0393    end
0394    
0395    meta = meta';
0396    fprintf('CACHE__:  Date+Time     bytes       Score_szPrio CountXEffort   Score_eff   #  obj_id ___\n');
0397    fprintf('%s b=%9.0d [%4d]  p=%02d t=%3dx%.2e [%4d] i=%4d: %s { %s }\n', ...
0398       meta{[c.time,c.size,c.score_sz,c.prio,c.count,c.effort,c.score_eff,N+1,c.obj_id, c.prop],:});
0399 
0400 function priidx = get_cache_priority
0401    global eidors_objects;
0402    priidx = [];
0403    if isfield(eidors_objects.cache, 'meta') && isfield(eidors_objects.cache, 'cols')
0404       meta = eidors_objects.cache.meta;
0405       c = eidors_objects.cache.cols;
0406       [jnk, priidx] = mysortrows(meta,[-c.score_eff c.score_sz -c.time]);
0407       priidx(priidx) = 1:size(meta,1);
0408    end
0409 
0410       
0411    
0412 function objid = clear_names_cache( name )
0413    objid=[];
0414    global eidors_objects;
0415    try
0416       c = eidors_objects.cache.cols;
0417       objid = find(strcmp(name, eidors_objects.cache.meta(:,c.prop)));
0418    end
0419    
0420    
0421 function remove_objids(idx, names, sizes)
0422    global eidors_objects;
0423    try
0424    c = eidors_objects.cache.cols;
0425    catch
0426       eidors_obj('cache_init'); 
0427       return % nothing else to do
0428    end
0429    if nargin == 0
0430       idx = 1:size(eidors_objects.cache.meta,1);
0431    end
0432    if isempty(idx)
0433       return
0434    end
0435    switch eidors_cache('debug_status')
0436       case 1
0437          debug_msg(  eidors_objects.cache.meta(idx,c.obj_id), ...
0438                      eidors_objects.cache.meta(idx,c.prop), 'removed');
0439       case 0.5
0440          db = eidors_cache('debug_status', eidors_objects.cache.meta(idx,c.prop));
0441          debug_msg(  eidors_objects.cache.meta(idx(db),c.obj_id), ...
0442                      eidors_objects.cache.meta(idx(db),c.prop), 'removed');
0443    end
0444    total_size = sum(cell2mat(eidors_objects.cache.meta(idx,c.size)));   
0445    N = numel(idx);
0446    if numel(idx) == size(eidors_objects.cache.meta,1)
0447       eidors_objects = rmfield(eidors_objects,'cache');
0448       eidors_obj('cache_init');
0449    else
0450       eidors_objects.cache = rmfield(eidors_objects.cache, ...
0451          eidors_objects.cache.meta(idx,c.obj_id));
0452       eidors_objects.cache.meta(idx,:) = [];
0453       eidors_objects.cache.size = eidors_objects.cache.size - total_size;
0454    end
0455    
0456    eidors_msg('Removed %d objects with %d bytes from cache', ...
0457       N, total_size, 2 );
0458    
0459        
0460 %   v1 = eidors_cache( @function_handle, {param1, param2, ...})
0461 function varargout = cache_shorthand(fhandle, varargin)
0462 % Will cache on all function inputs, unless opt.cache_obj is specified
0463    args = varargin{1};
0464    if ~iscell(args)
0465       args = {args};
0466    end
0467    
0468    if nargin >2
0469       opt = varargin{2};
0470    else
0471       opt = struct;
0472    end
0473    if ischar(opt)
0474       fstr = opt; clear opt;
0475       opt.fstr = fstr;
0476    end
0477    if isfield(opt, 'cache_obj');
0478       cache_obj = opt.cache_obj;
0479       if ~iscell(cache_obj)
0480          cache_obj = {cache_obj};
0481       end
0482    else
0483       cache_obj = args;
0484    end
0485    try
0486       fstr = opt.fstr;
0487    catch
0488       fstr = func2str(fhandle);
0489    end
0490    if isfield(opt, 'log_level')
0491        level_in = opt.log_level;
0492        level_out = opt.log_level;
0493    else
0494        level_in = 4;
0495        level_out = 3;
0496    end
0497    cache_to_disk = false;
0498    if isfield(opt, 'cache_to_disk')
0499        cache_locn    = opt.cache_to_disk;
0500        if cache_locn
0501           cache_to_disk = true;
0502        end
0503        if cache_locn==true
0504           cache_locn = '.';
0505        end
0506        if isfield(opt,'fstr')
0507           cache_str = opt.fstr;
0508        else
0509           cache_str = 'eidors_cache';
0510        end
0511    end
0512 
0513    [varargout,obj_id] = eidors_obj('get-cache', cache_obj, fstr );
0514    if length(varargout)==0 && cache_to_disk % if not in memory cache
0515        savename = [cache_locn,'/',cache_str,'_',obj_id,'.mat'];
0516        if exist(savename,'file')
0517           load(savename)
0518        end  
0519    end
0520    if numel(varargout) < nargout
0521       eidors_msg('@@ (Re)calculating %s',fstr, level_in);
0522       t0 = tic;
0523       [varargout{1:nargout}] =  ...
0524                feval(fhandle, args{:});
0525       t = toc(t0);
0526       if isfield(opt,'boost_priority');
0527          eidors_cache('boost_priority',opt.boost_priority);
0528       end
0529       
0530 
0531       if cache_to_disk
0532          eidors_msg('@@ Caching to %s', savename, level_in+1);
0533          save(savename,'varargout','-V7'); % -V7 for octave support
0534       else
0535          eidors_obj('set-cache', cache_obj, fstr, varargout, t);
0536       end
0537       
0538       if isfield(opt,'boost_priority');
0539          eidors_cache('boost_priority',-opt.boost_priority);
0540       end
0541       return
0542    end
0543    eidors_msg('%s: Using cached value',fstr,level_out);
0544 
0545 function debug_msg(id,name,action)
0546 global eidors_objects;
0547 if nargin < 3 
0548    action = name;
0549    name = fieldnames(eidors_objects.(id));
0550 end
0551 if isempty(id), return, end
0552 if ~iscell(name) name = {name}; end
0553 if ~iscell(id) id = {id}; end
0554 
0555 str = sprintf('EIDORS_CACHE: %s %%s { %%s }\\n', action);
0556 arr = [id, name]'; 
0557 
0558 fprintf(str, arr{:});
0559 % dbstack could be useful too
0560 
0561 function do_unit_test   
0562    ll= eidors_msg('log_level');
0563    eidors_msg('log_level',5);
0564    eidors_cache
0565    eidors_cache('clear_all');
0566    eidors_cache
0567    eidors_obj('set-cache', rand(1) , 't1', rand(2e3));
0568    eidors_obj('set-cache', rand(1) , 't2', rand(2e3));
0569    eidors_obj('set-cache', rand(1) , 't3', rand(2e3));
0570    eidors_cache
0571    eidors_cache list
0572    eidors_cache('clear_name','t3');
0573    eidors_cache
0574    eidors_cache list
0575    eidors_cache('clear_max', 34e6);
0576    eidors_cache
0577    eidors_cache('boost_priority', 1);
0578    eidors_cache
0579    eidors_cache('boost_priority', -1);
0580    eidors_cache
0581    [v1] = eidors_cache(@test_function,{3,4});
0582    [v2] = eidors_cache(@test_function,{3,4});
0583    unit_test_cmp('shorthand 1 param:',v1,v2);
0584    [v3 v4] = eidors_cache(@test_function,{3,4});
0585    unit_test_cmp('Expect Fail', v3, v4,-inf);
0586    [v5 v6 ] = eidors_cache(@test_function,{3,4});
0587    unit_test_cmp('shorthand 2 params:',v4, v6);
0588    [v5 v6 ] = eidors_cache(@test_function,{3,4, 5}); %this should re-calc
0589    opt.cache_obj = 5;
0590    [v5 v6 ] = eidors_cache(@test_function,{3,4, 5}, opt); %this should re-calc
0591    [v7 v8 ] = eidors_cache(@test_function,{1,2, 3}, opt); %this should NOT
0592    unit_test_cmp('shorthand cache_obj:',v6, v8);
0593    eidors_cache clear_all
0594    opt = struct;
0595    [v7 v8 ] = eidors_cache(@test_function,{1,2, 3}, opt); %this should NOT
0596    opt.boost_priority = 2;
0597    [v7 v8 ] = eidors_cache(@test_function,{3,4, 5}, opt); %this should NOT
0598    eidors_cache show_objs
0599    eidors_cache
0600    eidors_msg('log_level',ll);
0601    try
0602       eidors_cache(@(x) x^2, 3);
0603    catch
0604       eidors_msg('Error on anonymous function: correct',2);
0605    end
0606    test_debug
0607    test_priority
0608    test_disk_caching
0609  
0610 function [v1 v2] = test_function(a,b,c,d)
0611    v1 = rand(1);
0612    v2 = rand(1);
0613    
0614 function [meta,idx] = mysortrows(meta, cols)
0615    if ~exist('OCTAVE_VERSION') % octave doesn't sort cells (valid jun 2019)
0616       [meta,idx] = sortrows(meta, cols);
0617    else
0618       metm = cell2mat(meta(:,3:end));
0619       cols = ( abs(cols) - 2 ) .* sign(cols);
0620       [~,idx] = sortrows(metm, cols);
0621       meta = meta(idx,:);
0622    end
0623 
0624 
0625 function test_debug
0626    fprintf('\n\n************************\n        CACHE DEBUG: VERBOSE OUTPUT\n************************\n');
0627    eidors_cache clear
0628    eidors_obj('set-cache',{5}, 'test1',50);
0629    eidors_obj('set-cache',{5}, 'test2',500);
0630    eidors_obj('set-cache',{10}, 'test1',100);
0631    eidors_cache show_objs
0632    eidors_cache debug_off
0633    eidors_cache debug_on test2
0634    eidors_cache clear_name test2
0635    eidors_cache show_objs
0636 %    eidors_obj('set-cache',{5}, 'test1',50);
0637    eidors_obj('set-cache',{5}, 'test2',500);
0638    eidors_cache debug_off
0639    eidors_cache debug_on test1
0640    eidors_cache clear_name test2
0641    eidors_cache('clear_max',0)
0642    eidors_cache('show_objs')
0643    eidors_cache debug_off
0644    fprintf('\n\n************************\n        CACHE DEBUG: DEBUG FINISHED\n************************\n');
0645    
0646 function test_disk_caching
0647    tstdir = 'eidors_cache_test_dir1234321';
0648    [~]=rmdir(tstdir,'s');
0649    [~]=mkdir(tstdir);
0650    disp('============= DISK =============');
0651    opt = struct('cache_to_disk',tstdir);
0652    eidors_cache clear; global eidors_objects
0653    esz = length(fieldnames(eidors_objects.cache));
0654    unit_test_cmp('disk 00',length(dir([tstdir,'/*.mat'])),0)
0655    [v1]= eidors_cache( @sin, {1:100},opt);
0656    unit_test_cmp('disk 01',length(dir([tstdir,'/*.mat'])),1)
0657    unit_test_cmp('disk 02',0, ...
0658       length(fieldnames(eidors_objects.cache))-esz);
0659    obj_id = eidors_var_id({1:100,'sin'});
0660    cfname = [tstdir,'/eidors_cache_',obj_id,'.mat'];
0661    unit_test_cmp('disk 03',length(dir(cfname)),1); 
0662    loader = load(cfname);
0663    unit_test_cmp('disk 04',loader.varargout{1},v1);
0664 
0665    [v1]= eidors_cache( @sin, {1:100},opt);
0666    unit_test_cmp('disk 05',length(dir([tstdir,'/*.mat'])),1)
0667    unit_test_cmp('disk 06',0, ...
0668       length(fieldnames(eidors_objects.cache))-esz);
0669    loader = load(cfname);
0670    unit_test_cmp('disk 07',loader.varargout{1},v1);
0671    [~]=rmdir(tstdir,'s');
0672    disp('============= ~DISK =============');
0673    eidors_cache clear; global eidors_objects
0674    opt = struct('cache_to_disk',false);
0675    esz = length(fieldnames(eidors_objects.cache));
0676    [v1]= eidors_cache( @sin, {1:100},opt);
0677    unit_test_cmp('not disk 01',1, ...
0678       length(fieldnames(eidors_objects.cache))-esz);
0679    obj_id = eidors_var_id({1:100,'sin'});
0680    unit_test_cmp('not disk 02',1, ...
0681       length(fieldnames(eidors_objects.cache))-esz);
0682    unit_test_cmp('not disk 03',isfield(eidors_objects.cache,obj_id),1);
0683    unit_test_cmp('not disk 04',eidors_objects.cache.(obj_id),[v1]);
0684 
0685    [v1]= eidors_cache( @sin, {1:100},opt);
0686    unit_test_cmp('not disk 05',1, ...
0687       length(fieldnames(eidors_objects.cache))-esz);
0688 
0689    
0690 function test_priority
0691    eidors_cache clear
0692    eidors_obj('set-cache',{1}, 'slow_small', zeros(10) ,10); pause(.1)
0693 %    eidors_cache list
0694 %    fprintf('\n');
0695    eidors_obj('set-cache',{1}, 'slow_new',   zeros(100),10); pause(.1)
0696 %    eidors_cache list
0697 %    fprintf('\n');
0698    eidors_obj('set-cache',{1}, 'slow_big1',  zeros(100),10); pause(.1)
0699 %    eidors_cache list
0700 %    fprintf('\n');
0701    eidors_obj('set-cache',{1}, 'slow_big2',  zeros(100),20); pause(.1)
0702 %    eidors_cache list
0703 %    fprintf('\n');
0704    eidors_obj('set-cache',{1}, 'fast_small', zeros(2)  , 1); pause(.1)
0705 %    eidors_cache list
0706 %    fprintf('\n');
0707    eidors_obj('set-cache',{1}, 'fast_big',   zeros(100), 1); pause(.1)
0708 %    eidors_cache list
0709 %    fprintf('\n');
0710    eidors_obj('get-cache',{1}, 'slow_new'); 
0711    
0712    eidors_cache list
0713 
0714    
0715 %    obj= eidors_obj('get-cache',{5}, 'test1');

Generated on Tue 31-Dec-2019 17:03:26 by m2html © 2005