- Timestamp:
- 05/28/13 21:26:34 (3 years ago)
- Location:
- branches/decorate
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/decorate/memoize.py
r665 r666 2 2 decorators that cache results to memory, to file, or to a database 3 3 """ 4 from functools import update_wrapper, wraps as functools_wraps 5 from rounding import deep_round, simple_round 6 from archives import archive_dict 4 7 from keymaps import stringmap 5 from archives import archive_dict 6 from rounding import deep_round, simple_round 8 from cache import _CacheInfo 7 9 8 10 __all__ = ['memoize', 'memoized'] … … 11 13 #XXX: memoized fails when decorating a class method ??? 12 14 15 #XXX: essentially this is: cache.inf_cache(keymap=stringmap(flat=False)) 13 16 def memoized(cache=None, keymap=None, tol=None, deep=False): 14 17 """Decorator that memoizes a function's return value each time it is called. … … 23 26 deep = boolean for rounding depth (default is False, i.e. 'shallow') 24 27 """ 25 if keymap is None: keymap = stringmap(flat=False) 28 maxsize = None 29 30 if keymap is None: keymap = stringmap(flat=False) #XXX: hashmap(flat=True) 26 31 if cache is None: cache = archive_dict() 27 32 elif type(cache) is dict: cache = archive_dict(cache) … … 36 41 return (args, kwds) 37 42 38 def dec(f): 39 def func(*args, **kwds): 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): 40 51 try: 41 52 _args, _kwds = rounded_args(*args, **kwds) 42 argstr = keymap(*_args, **_kwds) 43 if cache.has_key(argstr): 44 return cache[argstr] 45 if cache.archived(): 46 cache.load(argstr) 47 if cache.has_key(argstr): 48 return cache[argstr] 49 res = f(*args, **kwds) 50 cache[argstr] = res #XXX: any automated dump to archive? 51 return res 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... 52 72 except: #TypeError 53 return f(*args, **kwds) 54 func.cache = cache 55 return func 56 return dec 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 57 105 58 106 … … 64 112 """ 65 113 def __init__(self, cache=None, keymap=None, tol=None, deep=False): 66 # self.func = func 67 if keymap is None: keymap = stringmap(flat=False) 114 self.__maxsize = None 115 if keymap is None: keymap = stringmap(flat=False) #XXX: hashmap(True) ? 68 116 if cache is None: cache = archive_dict() 69 117 elif type(cache) is dict: cache = archive_dict(cache) 70 self. cache = cache118 self.__cache = cache 71 119 self.__keymap = keymap 72 120 … … 80 128 return 81 129 82 def __call__(self, func):83 s elf.func = func84 import functools85 @functools.wraps(func) 86 def dec(*args, **kwds):130 def __call__(self, user_function): #XXX: i.e. 'decorating_function' 131 stats = [0, 0, 0] # make statistics updateable non-locally 132 HIT, MISS, LOAD = 0, 1, 2 # names for the stats fields 133 134 def wrapper(*args, **kwds): 87 135 try: 88 136 _args, _kwds = self.__rounded_args(*args, **kwds) 89 argstr = self.__keymap(*_args, **_kwds) 90 if self.cache.has_key(argstr): 91 return self.cache[argstr] 92 if self.cache.archived(): 93 self.cache.load(argstr) 94 if self.cache.has_key(argstr): 95 return self.cache[argstr] 96 res = self.func(*args, **kwds) 97 self.cache[argstr] = res 98 return res 137 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... 99 156 except: #TypeError 100 re turn self.func(*args, **kwds)101 return dec157 result = user_function(*args, **kwds) 158 return result 102 159 103 def __repr__(self): 104 """Return the function's docstring.""" 105 return self.func.__doc__ 160 def archive(obj): 161 """Replace the cache archive""" 162 self.__cache.archive = obj 163 164 def __get_cache(): 165 """Get the cache""" 166 return self.__cache 167 168 def clear(keepstats=False): 169 """Clear the cache and statistics""" 170 self.__cache.clear() 171 if not keepstats: stats[:] = [0, 0, 0] 172 173 def info(): 174 """Report cache statistics""" 175 return _CacheInfo(stats[HIT], stats[MISS], stats[LOAD], self.__maxsize, len(self.__cache)) 176 177 # interface 178 wrapper.__wrapped__ = user_function 179 wrapper.info = info 180 wrapper.clear = clear 181 wrapper.load = self.__cache.load 182 wrapper.dump = self.__cache.dump 183 wrapper.archive = archive 184 wrapper.archived = self.__cache.archived 185 wrapper.__cache__ = __get_cache 186 return update_wrapper(wrapper, user_function) 187 188 # def __repr__(self): 189 # """Return the function's docstring.""" 190 # return self.func.__doc__ 106 191 107 192 def __get__(self, obj, objtype): -
branches/decorate/test_cached_memoize.py
r665 r666 13 13 return fibonacci(n-1) + fibonacci(n-2) 14 14 15 fibonacci. cache.archive = file_archive('fibonacci.pkl')16 fibonacci. cache.load()15 fibonacci.archive(file_archive('fibonacci.pkl')) 16 fibonacci.load() 17 17 18 18 print fibonacci(7) 19 19 print fibonacci(9) 20 20 21 fibonacci. cache.dump()21 fibonacci.dump() 22 22 23 23 -
branches/decorate/test_memoize.py
r665 r666 118 118 add(1,2) 119 119 add(1,3) 120 print "db_cache = %s" % add. cache120 print "db_cache = %s" % add.__cache__() 121 121 122 122 @memoized(cache=dict()) … … 126 126 add(1,2) 127 127 add(1,3) 128 print "dict_cache = %s" % add. cache128 print "dict_cache = %s" % add.__cache__() 129 129 130 @memoized(cache=add. cache)130 @memoized(cache=add.__cache__()) 131 131 def add(x,y): 132 132 return x+y 133 133 add(1,2) 134 134 add(2,2) 135 print "re_dict_cache = %s" % add. cache135 print "re_dict_cache = %s" % add.__cache__() 136 136 137 137 @memoized(keymap=dumps) … … 141 141 add(1,2) 142 142 add(1,3) 143 print "pickle_dict_cache = %s" % add. cache143 print "pickle_dict_cache = %s" % add.__cache__() 144 144 145 145 -
branches/decorate/test_timed_monitor.py
r664 r666 174 174 print " upper bounds: %s" % upper_bounds 175 175 # print " ..." 176 try: model. cache.load()176 try: model.load() 177 177 except: pass 178 178 diameter = UQ(RVstart,RVend,lower_bounds,upper_bounds) 179 try: model. cache.dump()179 try: model.dump() 180 180 except: pass 181 181
Note: See TracChangeset
for help on using the changeset viewer.