Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 """Extensible memoizing collections and decorators.""" | |
|
Vadim Sh.
2017/06/23 18:26:50
please add README.swarming file describing where y
aludwin
2017/06/26 17:12:56
Done. Also updated the other README.swarming.
| |
| 2 | |
| 3 from __future__ import absolute_import | |
| 4 | |
| 5 import functools | |
| 6 | |
| 7 from . import keys | |
| 8 from .cache import Cache | |
| 9 from .lfu import LFUCache | |
| 10 from .lru import LRUCache | |
| 11 from .rr import RRCache | |
| 12 from .ttl import TTLCache | |
| 13 | |
| 14 __all__ = ( | |
| 15 'Cache', 'LFUCache', 'LRUCache', 'RRCache', 'TTLCache', | |
| 16 'cached', 'cachedmethod' | |
| 17 ) | |
| 18 | |
| 19 __version__ = '2.0.0' | |
| 20 | |
| 21 if hasattr(functools.update_wrapper(lambda f: f(), lambda: 42), '__wrapped__'): | |
| 22 _update_wrapper = functools.update_wrapper | |
| 23 else: | |
| 24 def _update_wrapper(wrapper, wrapped): | |
| 25 functools.update_wrapper(wrapper, wrapped) | |
| 26 wrapper.__wrapped__ = wrapped | |
| 27 return wrapper | |
| 28 | |
| 29 | |
| 30 def cached(cache, key=keys.hashkey, lock=None): | |
| 31 """Decorator to wrap a function with a memoizing callable that saves | |
| 32 results in a cache. | |
| 33 | |
| 34 """ | |
| 35 def decorator(func): | |
| 36 if cache is None: | |
| 37 def wrapper(*args, **kwargs): | |
| 38 return func(*args, **kwargs) | |
| 39 elif lock is None: | |
| 40 def wrapper(*args, **kwargs): | |
| 41 k = key(*args, **kwargs) | |
| 42 try: | |
| 43 return cache[k] | |
| 44 except KeyError: | |
| 45 pass # key not found | |
| 46 v = func(*args, **kwargs) | |
| 47 try: | |
| 48 cache[k] = v | |
| 49 except ValueError: | |
| 50 pass # value too large | |
| 51 return v | |
| 52 else: | |
| 53 def wrapper(*args, **kwargs): | |
| 54 k = key(*args, **kwargs) | |
| 55 try: | |
| 56 with lock: | |
| 57 return cache[k] | |
| 58 except KeyError: | |
| 59 pass # key not found | |
| 60 v = func(*args, **kwargs) | |
| 61 try: | |
| 62 with lock: | |
| 63 cache[k] = v | |
| 64 except ValueError: | |
| 65 pass # value too large | |
| 66 return v | |
| 67 return _update_wrapper(wrapper, func) | |
| 68 return decorator | |
| 69 | |
| 70 | |
| 71 def cachedmethod(cache, key=keys.hashkey, lock=None): | |
| 72 """Decorator to wrap a class or instance method with a memoizing | |
| 73 callable that saves results in a cache. | |
| 74 | |
| 75 """ | |
| 76 def decorator(method): | |
| 77 if lock is None: | |
| 78 def wrapper(self, *args, **kwargs): | |
| 79 c = cache(self) | |
| 80 if c is None: | |
| 81 return method(self, *args, **kwargs) | |
| 82 k = key(self, *args, **kwargs) | |
| 83 try: | |
| 84 return c[k] | |
| 85 except KeyError: | |
| 86 pass # key not found | |
| 87 v = method(self, *args, **kwargs) | |
| 88 try: | |
| 89 c[k] = v | |
| 90 except ValueError: | |
| 91 pass # value too large | |
| 92 return v | |
| 93 else: | |
| 94 def wrapper(self, *args, **kwargs): | |
| 95 c = cache(self) | |
| 96 if c is None: | |
| 97 return method(self, *args, **kwargs) | |
| 98 k = key(self, *args, **kwargs) | |
| 99 try: | |
| 100 with lock(self): | |
| 101 return c[k] | |
| 102 except KeyError: | |
| 103 pass # key not found | |
| 104 v = method(self, *args, **kwargs) | |
| 105 try: | |
| 106 with lock(self): | |
| 107 c[k] = v | |
| 108 except ValueError: | |
| 109 pass # value too large | |
| 110 return v | |
| 111 return _update_wrapper(wrapper, method) | |
| 112 return decorator | |
| OLD | NEW |