Changeset 667 for branches


Ignore:
Timestamp:
05/29/13 06:15:38 (3 years ago)
Author:
mmckerns
Message:

added a 'safe' cache version of all caches (makes memoized obsolete)

Location:
branches/decorate
Files:
4 edited
1 copied
2 moved

Legend:

Unmodified
Added
Removed
  • branches/decorate/cache.py

    r665 r667  
    5757 
    5858    keymap = kwd.get('keymap', None) 
    59     if keymap is None: keymap = hashmap(flat=True) #XXX: stringmap ? 
     59    if keymap is None: keymap = hashmap(flat=True) 
    6060    cache = archive_dict() 
    6161 
     
    7878 
    7979        def wrapper(*args, **kwds): 
    80             #XXX: add try/except... any failure has result = f(*args, **kwds) 
    8180            _args, _kwds = rounded_args(*args, **kwds) 
    8281            key = keymap(*_args, **_kwds) 
     
    106105            cache.archive = obj 
    107106 
     107        def __get_cache(): 
     108            """Get the cache""" 
     109            return cache 
     110 
    108111        def clear(keepstats=False): 
    109112            """Clear the cache and statistics""" 
     
    122125        wrapper.archive = archive 
    123126        wrapper.archived = cache.archived 
    124        #wrapper._cache = None  #XXX 
     127        wrapper.__cache__ = __get_cache 
    125128       #wrapper._queue = None  #XXX 
    126129        return update_wrapper(wrapper, user_function) 
     
    130133 
    131134def inf_cache(*arg, **kwd): 
    132     '''Infinitely-growing (INF) cache decorator. 
     135    '''infinitely-growing (INF) cache decorator. 
    133136 
    134137    This decorator memoizes a function's return value each time it is called. 
     
    162165 
    163166    keymap = kwd.get('keymap', None) 
    164     if keymap is None: keymap = hashmap(flat=True) #XXX: stringmap ? 
     167    if keymap is None: keymap = hashmap(flat=True) 
    165168    cache = kwd.get('cache', None) 
    166169    if cache is None: cache = archive_dict() 
     
    186189 
    187190        def wrapper(*args, **kwds): 
    188             #XXX: add try/except... any failure has result = f(*args, **kwds) 
    189191            _args, _kwds = rounded_args(*args, **kwds) 
    190192            key = keymap(*_args, **_kwds) 
     
    212214            cache.archive = obj 
    213215 
     216        def __get_cache(): 
     217            """Get the cache""" 
     218            return cache 
     219 
    214220        def clear(keepstats=False): 
    215221            """Clear the cache and statistics""" 
     
    229235        wrapper.archive = archive 
    230236        wrapper.archived = cache.archived 
    231        #wrapper._cache = cache #XXX 
     237        wrapper.__cache__ = __get_cache 
    232238       #wrapper._queue = None  #XXX 
    233239        return update_wrapper(wrapper, user_function) 
     
    237243 
    238244def lfu_cache(maxsize=100, cache=None, keymap=None, tol=None, deep=False): 
    239     '''Least-frequenty-used (LFU) cache decorator. 
     245    '''least-frequenty-used (LFU) cache decorator. 
    240246 
    241247    This decorator memoizes a function's return value each time it is called. 
     
    277283        return inf_cache(cache=cache, keymap=keymap, tol=tol, deep=deep) 
    278284 
    279     if keymap is None: keymap = hashmap(flat=True) #XXX: stringmap ? 
     285    if keymap is None: keymap = hashmap(flat=True) 
    280286    if cache is None: cache = archive_dict() 
    281287    elif type(cache) is dict: cache = archive_dict(cache) 
     
    299305 
    300306        def wrapper(*args, **kwds): 
    301             #XXX: add try/except... any failure has result = f(*args, **kwds) 
    302307            _args, _kwds = rounded_args(*args, **kwds) 
    303308            key = keymap(*_args, **_kwds) 
     
    340345            cache.archive = obj 
    341346 
     347        def __get_cache(): 
     348            """Get the cache""" 
     349            return cache 
     350 
    342351        def clear(keepstats=False): 
    343352            """Clear the cache and statistics""" 
     
    358367        wrapper.archive = archive 
    359368        wrapper.archived = cache.archived 
    360        #wrapper._cache = cache #XXX 
     369        wrapper.__cache__ = __get_cache 
    361370       #wrapper._queue = use_count #XXX 
    362371        return update_wrapper(wrapper, user_function) 
     
    366375 
    367376def lru_cache(maxsize=100, cache=None, keymap=None, tol=None, deep=False): 
    368     '''Least-recently-used (LRU) cache decorator. 
     377    '''least-recently-used (LRU) cache decorator. 
    369378 
    370379    This decorator memoizes a function's return value each time it is called. 
     
    407416    maxqueue = maxsize * 10 #XXX: user settable? confirm this works as expected 
    408417 
    409     if keymap is None: keymap = hashmap(flat=True) #XXX: stringmap ? 
     418    if keymap is None: keymap = hashmap(flat=True) 
    410419    if cache is None: cache = archive_dict() 
    411420    elif type(cache) is dict: cache = archive_dict(cache) 
     
    435444 
    436445        def wrapper(*args, **kwds): 
    437             #XXX: add try/except... any failure has result = f(*args, **kwds) 
    438446            _args, _kwds = rounded_args(*args, **kwds) 
    439447            key = keymap(*_args, **_kwds) 
     
    495503            cache.archive = obj 
    496504 
     505        def __get_cache(): 
     506            """Get the cache""" 
     507            return cache 
     508 
    497509        def clear(keepstats=False): 
    498510            """Clear the cache and statistics""" 
     
    514526        wrapper.archive = archive 
    515527        wrapper.archived = cache.archived 
    516        #wrapper._cache = cache #XXX 
     528        wrapper.__cache__ = __get_cache 
    517529       #wrapper._queue = queue #XXX 
    518530        return update_wrapper(wrapper, user_function) 
     
    522534 
    523535def mru_cache(maxsize=100, cache=None, keymap=None, tol=None, deep=False): 
    524     '''Most-recently-used (MRU) cache decorator. 
     536    '''most-recently-used (MRU) cache decorator. 
    525537 
    526538    This decorator memoizes a function's return value each time it is called. 
     
    562574        return inf_cache(cache=cache, keymap=keymap, tol=tol, deep=deep) 
    563575 
    564     if keymap is None: keymap = hashmap(flat=True) #XXX: stringmap ? 
     576    if keymap is None: keymap = hashmap(flat=True) 
    565577    if cache is None: cache = archive_dict() 
    566578    elif type(cache) is dict: cache = archive_dict(cache) 
     
    588600 
    589601        def wrapper(*args, **kwds): 
    590             #XXX: add try/except... any failure has result = f(*args, **kwds) 
    591602            _args, _kwds = rounded_args(*args, **kwds) 
    592603            key = keymap(*_args, **_kwds) 
     
    627638            cache.archive = obj 
    628639 
     640        def __get_cache(): 
     641            """Get the cache""" 
     642            return cache 
     643 
    629644        def clear(keepstats=False): 
    630645            """Clear the cache and statistics""" 
     
    645660        wrapper.archive = archive 
    646661        wrapper.archived = cache.archived 
    647        #wrapper._cache = cache #XXX 
     662        wrapper.__cache__ = __get_cache 
    648663       #wrapper._queue = queue #XXX 
    649664        return update_wrapper(wrapper, user_function) 
     
    693708        return inf_cache(cache=cache, keymap=keymap, tol=tol, deep=deep) 
    694709 
    695     if keymap is None: keymap = hashmap(flat=True) #XXX: stringmap ? 
     710    if keymap is None: keymap = hashmap(flat=True) 
    696711    if cache is None: cache = archive_dict() 
    697712    elif type(cache) is dict: cache = archive_dict(cache) 
     
    714729 
    715730        def wrapper(*args, **kwds): 
    716             #XXX: add try/except... any failure has result = f(*args, **kwds) 
    717731            _args, _kwds = rounded_args(*args, **kwds) 
    718732            key = keymap(*_args, **_kwds) 
     
    748762            cache.archive = obj 
    749763 
     764        def __get_cache(): 
     765            """Get the cache""" 
     766            return cache 
     767 
    750768        def clear(keepstats=False): 
    751769            """Clear the cache and statistics""" 
     
    765783        wrapper.archive = archive 
    766784        wrapper.archived = cache.archived 
    767        #wrapper._cache = None  #XXX 
     785        wrapper.__cache__ = __get_cache 
    768786       #wrapper._queue = None  #XXX 
    769787        return update_wrapper(wrapper, user_function) 
  • branches/decorate/memoize.py

    r666 r667  
    66from archives import archive_dict 
    77from keymaps import stringmap 
    8 from cache import _CacheInfo 
     8from cache import _CacheInfo, inf_cache 
    99 
    1010__all__ = ['memoize', 'memoized'] 
     
    1313#XXX: memoized fails when decorating a class method ??? 
    1414 
    15 #XXX: essentially this is: cache.inf_cache(keymap=stringmap(flat=False)) 
    16 def memoized(cache=None, keymap=None, tol=None, deep=False): 
    17     """Decorator that memoizes a function's return value each time it is called. 
    18     If called later with the same arguments, the memoized value is returned, and 
    19     not re-evaluated.  This may lead to memory issues, as cache is not cleared. 
    20     This decorator takes an integer tolerance 'tol', equal to the number of 
    21     decimal places to which it will round off floats. 
    22  
    23     cache = storage hashmap (default is {}) 
    24     keymap = cache key encoder (default is keymaps.stringmap(flat=False)) 
    25     tol = integer tolerance for rounding (default is None) 
    26     deep = boolean for rounding depth (default is False, i.e. 'shallow') 
    27     """ 
    28     maxsize = None 
    29  
    30     if keymap is None: keymap = stringmap(flat=False) #XXX: hashmap(flat=True) 
    31     if cache is None: cache = archive_dict() 
    32     elif type(cache) is dict: cache = archive_dict(cache) 
    33     # does archive make sense with database, file, ?... (requires more thought) 
    34  
    35     if deep: rounded = deep_round 
    36     else: rounded = simple_round 
    37    #else: rounded = shallow_round #FIXME: slow 
    38  
    39     @rounded(tol) 
    40     def rounded_args(*args, **kwds): 
    41         return (args, kwds) 
    42  
    43     def decorating_function(user_function): 
    44         _len = len                      # localize the global len() function 
    45         stats = [0, 0, 0]               # make statistics updateable non-locally 
    46         HIT, MISS, LOAD = 0, 1, 2       # names for the stats fields 
    47         _len = len                      # localize the global len() function 
    48        #lock = RLock()                  # linkedlist updates aren't threadsafe 
    49  
    50         def wrapper(*args, **kwds): 
    51             try: 
    52                 _args, _kwds = rounded_args(*args, **kwds) 
    53                 key = keymap(*_args, **_kwds) 
    54  
    55                 try: 
    56                     # get cache entry 
    57                     result = cache[key] 
    58                     stats[HIT] += 1 
    59                 except KeyError: 
    60                     # if not in cache, look in archive 
    61                     if cache.archived(): 
    62                         cache.load(key) 
    63                     try: 
    64                         result = cache[key] 
    65                         stats[LOAD] += 1 
    66                     except KeyError: 
    67                         # if not found, then compute 
    68                         result = user_function(*args, **kwds) 
    69                         cache[key] = result 
    70                         stats[MISS] += 1 
    71                     #XXX:  NO cache purge... 
    72             except: #TypeError 
    73                 result = user_function(*args, **kwds) 
    74             return result 
    75  
    76         def archive(obj): 
    77             """Replace the cache archive""" 
    78             cache.archive = obj 
    79  
    80         def __get_cache(): 
    81             """Get the cache""" 
    82             return cache 
    83  
    84         def clear(keepstats=False): 
    85             """Clear the cache and statistics""" 
    86             cache.clear() 
    87             if not keepstats: stats[:] = [0, 0, 0] 
    88  
    89         def info(): 
    90             """Report cache statistics""" 
    91             return _CacheInfo(stats[HIT], stats[MISS], stats[LOAD], maxsize, len(cache)) 
    92  
    93         # interface 
    94         wrapper.__wrapped__ = user_function 
    95         wrapper.info = info 
    96         wrapper.clear = clear 
    97         wrapper.load = cache.load 
    98         wrapper.dump = cache.dump 
    99         wrapper.archive = archive 
    100         wrapper.archived = cache.archived 
    101         wrapper.__cache__ = __get_cache 
    102         return update_wrapper(wrapper, user_function) 
    103  
    104     return decorating_function 
    105  
     15# backward compatibility 
     16memoized = inf_cache 
    10617 
    10718class memoize(object): 
    108     """Decorator that memoizes a function's return value each time it is called. 
     19    """This is safecache.inf_cache implemented as a class-based decorator. 
     20 
     21    Decorator that memoizes a function's return value each time it is called. 
    10922    If called later with the same arguments, the memoized value is returned, and 
    11023    not re-evaluated.  This may lead to memory issues, as cache is not cleared. 
     
    11326    def __init__(self, cache=None, keymap=None, tol=None, deep=False): 
    11427        self.__maxsize = None 
    115         if keymap is None: keymap = stringmap(flat=False) #XXX: hashmap(True) ? 
     28        if keymap is None: keymap = stringmap(flat=False) 
    11629        if cache is None: cache = archive_dict() 
    11730        elif type(cache) is dict: cache = archive_dict(cache) 
     
    12841        return 
    12942 
    130     def __call__(self, user_function): #XXX: i.e. 'decorating_function' 
     43    def __call__(self, user_function):  # i.e. 'decorating_function' 
    13144        stats = [0, 0, 0]               # make statistics updateable non-locally 
    13245        HIT, MISS, LOAD = 0, 1, 2       # names for the stats fields 
     
    13649                _args, _kwds = self.__rounded_args(*args, **kwds) 
    13750                key = self.__keymap(*_args, **_kwds) 
    138  
    139                 try: 
    140                     # get cache entry 
    141                     result = self.__cache[key] 
    142                     stats[HIT] += 1 
    143                 except KeyError: 
    144                     # if not in cache, look in archive 
    145                     if self.__cache.archived(): 
    146                         self.__cache.load(key) 
    147                     try: 
    148                         result = self.__cache[key] 
    149                         stats[LOAD] += 1 
    150                     except KeyError: 
    151                         # if not found, then compute 
    152                         result = user_function(*args, **kwds) 
    153                         self.__cache[key] = result 
    154                         stats[MISS] += 1 
    155                     #XXX:  NO cache purge... 
    15651            except: #TypeError 
    15752                result = user_function(*args, **kwds) 
     53                return result 
     54 
     55            try: 
     56                # get cache entry 
     57                result = self.__cache[key] 
     58                stats[HIT] += 1 
     59            except KeyError: 
     60                # if not in cache, look in archive 
     61                if self.__cache.archived(): 
     62                    self.__cache.load(key) 
     63                try: 
     64                    result = self.__cache[key] 
     65                    stats[LOAD] += 1 
     66                except KeyError: 
     67                    # if not found, then compute 
     68                    result = user_function(*args, **kwds) 
     69                    self.__cache[key] = result 
     70                    stats[MISS] += 1 
    15871            return result 
    15972 
  • branches/decorate/safecache.py

    r665 r667  
    1414from rounding import deep_round, simple_round 
    1515from archives import archive_dict 
    16 from keymaps import hashmap 
     16from keymaps import stringmap 
     17from cache import Counter 
    1718 
    1819_CacheInfo = namedtuple("CacheInfo", ['hit','miss','load','maxsize','size']) 
    1920 
    20 class Counter(dict): 
    21     'Mapping where default values are zero' 
    22     def __missing__(self, key): 
    23         return 0 
    24  
    2521#XXX: what about caches that expire due to time, calls, etc... 
    26 #XXX: check the impact of not serializing by default, and hashmap by default 
     22#XXX: check the impact of not serializing by default, and stringmap by default 
    2723 
    2824def no_cache(*arg, **kwd): 
    29     '''empty (NO) cache decorator. 
     25    ''''safe' version of the empty (NO) cache decorator. 
    3026 
    3127    Unlike other cache decorators, this decorator does not cache.  It is a 
     
    3531    rounding on inputs will be 'shallow' or 'deep'. 
    3632 
    37     keymap = cache key encoder (default is keymaps.hashmap(flat=True)) 
     33    keymap = cache key encoder (default is keymaps.stringmap(flat=False)) 
    3834    tol = integer tolerance for rounding (default is None) 
    3935    deep = boolean for rounding depth (default is False, i.e. 'shallow') 
     
    4137    If *keymap* is given, it will replace the hashing algorithm for generating 
    4238    cache keys.  Several hashing algorithms are available in 'keymaps'. The 
    43     default keymap requires arguments to the cached function to be hashable. 
     39    default keymap does not require arguments to the cached function to be 
     40    hashable.  If a hashing error occurs, the cached function will be evaluated. 
    4441 
    4542    If the keymap retains type information, then arguments of different types 
     
    5754 
    5855    keymap = kwd.get('keymap', None) 
    59     if keymap is None: keymap = hashmap(flat=True) #XXX: stringmap ? 
     56    if keymap is None: keymap = stringmap(flat=False) 
    6057    cache = archive_dict() 
    6158 
     
    7875 
    7976        def wrapper(*args, **kwds): 
    80             #XXX: add try/except... any failure has result = f(*args, **kwds) 
    81             _args, _kwds = rounded_args(*args, **kwds) 
    82             key = keymap(*_args, **_kwds) 
     77            try: 
     78                _args, _kwds = rounded_args(*args, **kwds) 
     79                key = keymap(*_args, **_kwds) 
     80            except: #TypeError 
     81                result = user_function(*args, **kwds) 
     82                return result 
    8383 
    8484            # look in archive 
     
    106106            cache.archive = obj 
    107107 
     108        def __get_cache(): 
     109            """Get the cache""" 
     110            return cache 
     111 
    108112        def clear(keepstats=False): 
    109113            """Clear the cache and statistics""" 
     
    122126        wrapper.archive = archive 
    123127        wrapper.archived = cache.archived 
    124        #wrapper._cache = None  #XXX 
     128        wrapper.__cache__ = __get_cache 
    125129       #wrapper._queue = None  #XXX 
    126130        return update_wrapper(wrapper, user_function) 
     
    130134 
    131135def inf_cache(*arg, **kwd): 
    132     '''Infinitely-growing (INF) cache decorator. 
     136    ''''safe' version of the infinitely-growing (INF) cache decorator. 
    133137 
    134138    This decorator memoizes a function's return value each time it is called. 
     
    141145 
    142146    cache = storage hashmap (default is {}) 
    143     keymap = cache key encoder (default is keymaps.hashmap(flat=True)) 
     147    keymap = cache key encoder (default is keymaps.stringmap(flat=False)) 
    144148    tol = integer tolerance for rounding (default is None) 
    145149    deep = boolean for rounding depth (default is False, i.e. 'shallow') 
     
    147151    If *keymap* is given, it will replace the hashing algorithm for generating 
    148152    cache keys.  Several hashing algorithms are available in 'keymaps'. The 
    149     default keymap requires arguments to the cached function to be hashable. 
     153    default keymap does not require arguments to the cached function to be 
     154    hashable.  If a hashing error occurs, the cached function will be evaluated. 
    150155 
    151156    If the keymap retains type information, then arguments of different types 
     
    162167 
    163168    keymap = kwd.get('keymap', None) 
    164     if keymap is None: keymap = hashmap(flat=True) #XXX: stringmap ? 
     169    if keymap is None: keymap = stringmap(flat=False) 
    165170    cache = kwd.get('cache', None) 
    166171    if cache is None: cache = archive_dict() 
     
    186191 
    187192        def wrapper(*args, **kwds): 
    188             #XXX: add try/except... any failure has result = f(*args, **kwds) 
    189             _args, _kwds = rounded_args(*args, **kwds) 
    190             key = keymap(*_args, **_kwds) 
     193            try: 
     194                _args, _kwds = rounded_args(*args, **kwds) 
     195                key = keymap(*_args, **_kwds) 
     196            except: #TypeError 
     197                result = user_function(*args, **kwds) 
     198                return result 
    191199 
    192200            try: 
     
    212220            cache.archive = obj 
    213221 
     222        def __get_cache(): 
     223            """Get the cache""" 
     224            return cache 
     225 
    214226        def clear(keepstats=False): 
    215227            """Clear the cache and statistics""" 
     
    229241        wrapper.archive = archive 
    230242        wrapper.archived = cache.archived 
    231        #wrapper._cache = cache #XXX 
     243        wrapper.__cache__ = __get_cache 
    232244       #wrapper._queue = None  #XXX 
    233245        return update_wrapper(wrapper, user_function) 
     
    237249 
    238250def lfu_cache(maxsize=100, cache=None, keymap=None, tol=None, deep=False): 
    239     '''Least-frequenty-used (LFU) cache decorator. 
     251    ''''safe' version of the least-frequenty-used (LFU) cache decorator. 
    240252 
    241253    This decorator memoizes a function's return value each time it is called. 
     
    250262    maxsize = maximum cache size 
    251263    cache = storage hashmap (default is {}) 
    252     keymap = cache key encoder (default is keymaps.hashmap(flat=True)) 
     264    keymap = cache key encoder (default is keymaps.stringmap(flat=False)) 
    253265    tol = integer tolerance for rounding (default is None) 
    254266    deep = boolean for rounding depth (default is False, i.e. 'shallow') 
     
    258270    If *keymap* is given, it will replace the hashing algorithm for generating 
    259271    cache keys.  Several hashing algorithms are available in 'keymaps'. The 
    260     default keymap requires arguments to the cached function to be hashable. 
     272    default keymap does not require arguments to the cached function to be 
     273    hashable.  If a hashing error occurs, the cached function will be evaluated. 
    261274 
    262275    If the keymap retains type information, then arguments of different types 
     
    277290        return inf_cache(cache=cache, keymap=keymap, tol=tol, deep=deep) 
    278291 
    279     if keymap is None: keymap = hashmap(flat=True) #XXX: stringmap ? 
     292    if keymap is None: keymap = stringmap(flat=False) 
    280293    if cache is None: cache = archive_dict() 
    281294    elif type(cache) is dict: cache = archive_dict(cache) 
     
    299312 
    300313        def wrapper(*args, **kwds): 
    301             #XXX: add try/except... any failure has result = f(*args, **kwds) 
    302             _args, _kwds = rounded_args(*args, **kwds) 
    303             key = keymap(*_args, **_kwds) 
     314            try: 
     315                _args, _kwds = rounded_args(*args, **kwds) 
     316                key = keymap(*_args, **_kwds) 
     317            except: #TypeError 
     318                result = user_function(*args, **kwds) 
     319                return result 
    304320 
    305321            try: 
     
    340356            cache.archive = obj 
    341357 
     358        def __get_cache(): 
     359            """Get the cache""" 
     360            return cache 
     361 
    342362        def clear(keepstats=False): 
    343363            """Clear the cache and statistics""" 
     
    358378        wrapper.archive = archive 
    359379        wrapper.archived = cache.archived 
    360        #wrapper._cache = cache #XXX 
     380        wrapper.__cache__ = __get_cache 
    361381       #wrapper._queue = use_count #XXX 
    362382        return update_wrapper(wrapper, user_function) 
     
    366386 
    367387def lru_cache(maxsize=100, cache=None, keymap=None, tol=None, deep=False): 
    368     '''Least-recently-used (LRU) cache decorator. 
     388    ''''safe' version of the least-recently-used (LRU) cache decorator. 
    369389 
    370390    This decorator memoizes a function's return value each time it is called. 
     
    379399    maxsize = maximum cache size 
    380400    cache = storage hashmap (default is {}) 
    381     keymap = cache key encoder (default is keymaps.hashmap(flat=True)) 
     401    keymap = cache key encoder (default is keymaps.stringmap(flat=False)) 
    382402    tol = integer tolerance for rounding (default is None) 
    383403    deep = boolean for rounding depth (default is False, i.e. 'shallow') 
     
    387407    If *keymap* is given, it will replace the hashing algorithm for generating 
    388408    cache keys.  Several hashing algorithms are available in 'keymaps'. The 
    389     default keymap requires arguments to the cached function to be hashable. 
     409    default keymap does not require arguments to the cached function to be 
     410    hashable.  If a hashing error occurs, the cached function will be evaluated. 
    390411 
    391412    If the keymap retains type information, then arguments of different types 
     
    407428    maxqueue = maxsize * 10 #XXX: user settable? confirm this works as expected 
    408429 
    409     if keymap is None: keymap = hashmap(flat=True) #XXX: stringmap ? 
     430    if keymap is None: keymap = stringmap(flat=False) 
    410431    if cache is None: cache = archive_dict() 
    411432    elif type(cache) is dict: cache = archive_dict(cache) 
     
    435456 
    436457        def wrapper(*args, **kwds): 
    437             #XXX: add try/except... any failure has result = f(*args, **kwds) 
    438             _args, _kwds = rounded_args(*args, **kwds) 
    439             key = keymap(*_args, **_kwds) 
     458            try: 
     459                _args, _kwds = rounded_args(*args, **kwds) 
     460                key = keymap(*_args, **_kwds) 
     461            except: #TypeError 
     462                result = user_function(*args, **kwds) 
     463                return result 
    440464 
    441465            try: 
     
    495519            cache.archive = obj 
    496520 
     521        def __get_cache(): 
     522            """Get the cache""" 
     523            return cache 
     524 
    497525        def clear(keepstats=False): 
    498526            """Clear the cache and statistics""" 
     
    514542        wrapper.archive = archive 
    515543        wrapper.archived = cache.archived 
    516        #wrapper._cache = cache #XXX 
     544        wrapper.__cache__ = __get_cache 
    517545       #wrapper._queue = queue #XXX 
    518546        return update_wrapper(wrapper, user_function) 
     
    522550 
    523551def mru_cache(maxsize=100, cache=None, keymap=None, tol=None, deep=False): 
    524     '''Most-recently-used (MRU) cache decorator. 
     552    ''''safe' version of the most-recently-used (MRU) cache decorator. 
    525553 
    526554    This decorator memoizes a function's return value each time it is called. 
     
    535563    maxsize = maximum cache size 
    536564    cache = storage hashmap (default is {}) 
    537     keymap = cache key encoder (default is keymaps.hashmap(flat=True)) 
     565    keymap = cache key encoder (default is keymaps.stringmap(flat=False)) 
    538566    tol = integer tolerance for rounding (default is None) 
    539567    deep = boolean for rounding depth (default is False, i.e. 'shallow') 
     
    543571    If *keymap* is given, it will replace the hashing algorithm for generating 
    544572    cache keys.  Several hashing algorithms are available in 'keymaps'. The 
    545     default keymap requires arguments to the cached function to be hashable. 
     573    default keymap does not require arguments to the cached function to be 
     574    hashable.  If a hashing error occurs, the cached function will be evaluated. 
    546575 
    547576    If the keymap retains type information, then arguments of different types 
     
    562591        return inf_cache(cache=cache, keymap=keymap, tol=tol, deep=deep) 
    563592 
    564     if keymap is None: keymap = hashmap(flat=True) #XXX: stringmap ? 
     593    if keymap is None: keymap = stringmap(flat=False) 
    565594    if cache is None: cache = archive_dict() 
    566595    elif type(cache) is dict: cache = archive_dict(cache) 
     
    588617 
    589618        def wrapper(*args, **kwds): 
    590             #XXX: add try/except... any failure has result = f(*args, **kwds) 
    591             _args, _kwds = rounded_args(*args, **kwds) 
    592             key = keymap(*_args, **_kwds) 
     619            try: 
     620                _args, _kwds = rounded_args(*args, **kwds) 
     621                key = keymap(*_args, **_kwds) 
     622            except: #TypeError 
     623                result = user_function(*args, **kwds) 
     624                return result 
    593625 
    594626            try: 
     
    627659            cache.archive = obj 
    628660 
     661        def __get_cache(): 
     662            """Get the cache""" 
     663            return cache 
     664 
    629665        def clear(keepstats=False): 
    630666            """Clear the cache and statistics""" 
     
    645681        wrapper.archive = archive 
    646682        wrapper.archived = cache.archived 
    647        #wrapper._cache = cache #XXX 
     683        wrapper.__cache__ = __get_cache 
    648684       #wrapper._queue = queue #XXX 
    649685        return update_wrapper(wrapper, user_function) 
     
    653689 
    654690def rr_cache(maxsize=100, cache=None, keymap=None, tol=None, deep=False): 
    655     '''random-replacement (RR) cache decorator. 
     691    ''''safe' version of the random-replacement (RR) cache decorator. 
    656692 
    657693    This decorator memoizes a function's return value each time it is called. 
     
    666702    maxsize = maximum cache size 
    667703    cache = storage hashmap (default is {}) 
    668     keymap = cache key encoder (default is keymaps.hashmap(flat=True)) 
     704    keymap = cache key encoder (default is keymaps.stringmap(flat=False)) 
    669705    tol = integer tolerance for rounding (default is None) 
    670706    deep = boolean for rounding depth (default is False, i.e. 'shallow') 
     
    674710    If *keymap* is given, it will replace the hashing algorithm for generating 
    675711    cache keys.  Several hashing algorithms are available in 'keymaps'. The 
    676     default keymap requires arguments to the cached function to be hashable. 
     712    default keymap does not require arguments to the cached function to be 
     713    hashable.  If a hashing error occurs, the cached function will be evaluated. 
    677714 
    678715    If the keymap retains type information, then arguments of different types 
     
    693730        return inf_cache(cache=cache, keymap=keymap, tol=tol, deep=deep) 
    694731 
    695     if keymap is None: keymap = hashmap(flat=True) #XXX: stringmap ? 
     732    if keymap is None: keymap = stringmap(flat=False) 
    696733    if cache is None: cache = archive_dict() 
    697734    elif type(cache) is dict: cache = archive_dict(cache) 
     
    714751 
    715752        def wrapper(*args, **kwds): 
    716             #XXX: add try/except... any failure has result = f(*args, **kwds) 
    717             _args, _kwds = rounded_args(*args, **kwds) 
    718             key = keymap(*_args, **_kwds) 
     753            try: 
     754                _args, _kwds = rounded_args(*args, **kwds) 
     755                key = keymap(*_args, **_kwds) 
     756            except: #TypeError 
     757                result = user_function(*args, **kwds) 
     758                return result 
    719759 
    720760            try: 
     
    748788            cache.archive = obj 
    749789 
     790        def __get_cache(): 
     791            """Get the cache""" 
     792            return cache 
     793 
    750794        def clear(keepstats=False): 
    751795            """Clear the cache and statistics""" 
     
    765809        wrapper.archive = archive 
    766810        wrapper.archived = cache.archived 
    767        #wrapper._cache = None  #XXX 
     811        wrapper.__cache__ = __get_cache 
    768812       #wrapper._queue = None  #XXX 
    769813        return update_wrapper(wrapper, user_function) 
  • branches/decorate/surrogate.py

    r665 r667  
    2020 
    2121 
    22 from memoize import memoized 
     22from safecache import inf_cache as memoized 
     23#from cache import inf_cache as memoized 
    2324from archives import archive_dict, file_archive 
    24 from keymaps import picklemap, hashmap 
     25from keymaps import picklemap, stringmap, hashmap 
    2526dumps = picklemap(flat=False) 
     27encode = stringmap(flat=False) 
     28hashed = hashmap(flat=False) 
    2629cache = archive_dict(archive=file_archive('surrogate.pkl')) 
    2730#@memoized(keymap=dumps, tol=0, deep=True) # slower, but more robust 
    28 #@memoized(tol=0, deep=True) 
     31#@memoized(keymap=encode, tol=0, deep=True) 
    2932#@memoized(cache=cache, keymap=dumps)    # slower, but more robust 
    30 @memoized(cache=cache) 
     33#@memoized(cache=cache, keymap=hashed)   # fails to cache (unhashable) 
     34@memoized(cache=cache, keymap=encode) 
    3135def marc_surr(x): 
    3236  """calculate perforation area using a tanh-based model surrogate 
  • branches/decorate/test_cache.py

    r666 r667  
    2121""" 
    2222 
    23 from memoize import memoized 
    24 #from memoize import memoize 
     23#from safecache import inf_cache as memoized 
     24from cache import inf_cache as memoized 
    2525from timer import timed 
    2626from keymaps import picklemap 
  • branches/decorate/test_cached.py

    r666 r667  
    1 from memoize import memoized 
     1#from safecache import inf_cache as memoized 
     2from cache import inf_cache as memoized 
    23from archives import file_archive 
    34from timer import timed 
  • branches/decorate/test_timed_monitor.py

    r666 r667  
    179179  try: model.dump() 
    180180  except: pass 
     181  try: print model.info() 
     182  except: pass 
    181183 
    182184# EOF 
Note: See TracChangeset for help on using the changeset viewer.