Changeset 590 for branches


Ignore:
Timestamp:
11/13/12 19:10:10 (4 years ago)
Author:
mmckerns
Message:

added reading and writing to disk archive for memoize

Location:
branches/decorate
Files:
1 added
1 edited

Legend:

Unmodified
Added
Removed
  • branches/decorate/memoize.py

    r587 r590  
    5050 
    5151 
     52def get_archive(archive): 
     53    import dill as pickle 
     54    try: 
     55        f = open(archive, 'rb') 
     56        cache = pickle.load(f) 
     57        f.close() 
     58    except: 
     59        cache = {} 
     60    return cache 
     61 
     62 
     63def load_factory(memo=None): 
     64    if memo is None: memo = {} 
     65    def load(archive=None, *args): 
     66        cache = get_archive(archive) 
     67        if not args: 
     68            memo.update(cache) 
     69        for arg in args: 
     70            if cache.has_key(arg): 
     71                memo.update({arg:cache[arg]}) 
     72        cache.clear() 
     73        return 
     74    return load 
     75 
     76 
     77def dump_factory(memo=None): 
     78    if memo is None: memo = {} 
     79    import dill as pickle 
     80    def dump(archive=None, *args): 
     81        cache = get_archive(archive) 
     82        for arg in args: 
     83            if memo.has_key(arg): 
     84                cache.update({arg:memo[arg]}) 
     85        if not args: 
     86            cache.update(memo) 
     87        try: 
     88            f = open(archive, 'wb') 
     89            pickle.dump(cache, f) 
     90        except: 
     91            pass  #XXX: warning? fail? 
     92        cache.clear() 
     93        return 
     94    return dump 
     95 
     96 
    5297#FIXME: the below need expiration of cache due to time, calls, etc... 
    5398#       and potentially r/w to database, file, or other caching mechanism 
    5499#FIXME: memoize*_round fails when decorating a class method 
    55100 
     101#FIXME: resolve signature difference...  @memoized versus @memoized() 
    56102 
    57103def memoized0_nopickle_round(tol=0): 
     
    110156                return f(*args, **kwds) 
    111157        func.memo = memo 
     158        return func 
     159    return dec 
     160 
     161 
     162 
     163# Want: 
     164# - if has archive, then can try reading archive if not found in memory 
     165# - if has archive, then can write to archive upon evaluation 
     166# - load an archive / update an existing archive 
     167# - save some or all of memo to archive 
     168def memoized0_nopickle_archived(): 
     169    """Decorator that memoizes a function's return value each time it is called. 
     170    If called later with the same arguments, the memoized value is returned, and 
     171    not re-evaluated.  This may lead to memory issues, as memo is never cleared. 
     172    This decorator takes an integer tolerance 'tol', equal to the number of 
     173    decimal places to which it will round off floats. 
     174    """ 
     175    memo = {} 
     176    load = load_factory(memo) 
     177    dump = dump_factory(memo) 
     178 
     179    def dec(f): 
     180        def func(*args, **kwds): 
     181            try: 
     182                argstr = str((args, kwds)) 
     183                if not memo.has_key(argstr): 
     184                    load(argstr) 
     185                if not memo.has_key(argstr): 
     186                    memo[argstr] = f(*args, **kwds) 
     187                return memo[argstr] 
     188            except: #TypeError 
     189                return f(*args, **kwds) 
     190        func.memo = memo 
     191        func.load = load 
     192        func.dump = dump 
     193        return func 
     194    return dec 
     195 
     196 
     197def memoized0_archived(): 
     198    """Decorator that memoizes a function's return value each time it is called. 
     199    If called later with the same arguments, the memoized value is returned, and 
     200    not re-evaluated.  This may lead to memory issues, as memo is never cleared. 
     201    This decorator takes an integer tolerance 'tol', equal to the number of 
     202    decimal places to which it will round off floats. 
     203    """ 
     204    memo = {} 
     205    load = load_factory(memo) 
     206    dump = dump_factory(memo) 
     207 
     208    def dec(f): 
     209        def func(*args, **kwds): 
     210            try: 
     211               #import cPickle as pickle 
     212                import dill as pickle 
     213                argstr = pickle.dumps((args, kwds)) 
     214                if not memo.has_key(argstr): 
     215                    load(argstr) 
     216                if not memo.has_key(argstr): 
     217                    memo[argstr] = f(*args, **kwds) 
     218                return memo[argstr]  #XXX: any automated dump to archive? 
     219            except: #TypeError 
     220                return f(*args, **kwds) 
     221        func.memo = memo 
     222        func.load = load  #XXX: only use with no arguments? 
     223        func.dump = dump  #XXX: only use with no arguments? 
    112224        return func 
    113225    return dec 
Note: See TracChangeset for help on using the changeset viewer.