Chromium Code Reviews| Index: client/third_party/cachetools/__init__.py |
| diff --git a/client/third_party/cachetools/__init__.py b/client/third_party/cachetools/__init__.py |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..646997009fcf22addc77219d7e861b227c1081f4 |
| --- /dev/null |
| +++ b/client/third_party/cachetools/__init__.py |
| @@ -0,0 +1,112 @@ |
| +"""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.
|
| + |
| +from __future__ import absolute_import |
| + |
| +import functools |
| + |
| +from . import keys |
| +from .cache import Cache |
| +from .lfu import LFUCache |
| +from .lru import LRUCache |
| +from .rr import RRCache |
| +from .ttl import TTLCache |
| + |
| +__all__ = ( |
| + 'Cache', 'LFUCache', 'LRUCache', 'RRCache', 'TTLCache', |
| + 'cached', 'cachedmethod' |
| +) |
| + |
| +__version__ = '2.0.0' |
| + |
| +if hasattr(functools.update_wrapper(lambda f: f(), lambda: 42), '__wrapped__'): |
| + _update_wrapper = functools.update_wrapper |
| +else: |
| + def _update_wrapper(wrapper, wrapped): |
| + functools.update_wrapper(wrapper, wrapped) |
| + wrapper.__wrapped__ = wrapped |
| + return wrapper |
| + |
| + |
| +def cached(cache, key=keys.hashkey, lock=None): |
| + """Decorator to wrap a function with a memoizing callable that saves |
| + results in a cache. |
| + |
| + """ |
| + def decorator(func): |
| + if cache is None: |
| + def wrapper(*args, **kwargs): |
| + return func(*args, **kwargs) |
| + elif lock is None: |
| + def wrapper(*args, **kwargs): |
| + k = key(*args, **kwargs) |
| + try: |
| + return cache[k] |
| + except KeyError: |
| + pass # key not found |
| + v = func(*args, **kwargs) |
| + try: |
| + cache[k] = v |
| + except ValueError: |
| + pass # value too large |
| + return v |
| + else: |
| + def wrapper(*args, **kwargs): |
| + k = key(*args, **kwargs) |
| + try: |
| + with lock: |
| + return cache[k] |
| + except KeyError: |
| + pass # key not found |
| + v = func(*args, **kwargs) |
| + try: |
| + with lock: |
| + cache[k] = v |
| + except ValueError: |
| + pass # value too large |
| + return v |
| + return _update_wrapper(wrapper, func) |
| + return decorator |
| + |
| + |
| +def cachedmethod(cache, key=keys.hashkey, lock=None): |
| + """Decorator to wrap a class or instance method with a memoizing |
| + callable that saves results in a cache. |
| + |
| + """ |
| + def decorator(method): |
| + if lock is None: |
| + def wrapper(self, *args, **kwargs): |
| + c = cache(self) |
| + if c is None: |
| + return method(self, *args, **kwargs) |
| + k = key(self, *args, **kwargs) |
| + try: |
| + return c[k] |
| + except KeyError: |
| + pass # key not found |
| + v = method(self, *args, **kwargs) |
| + try: |
| + c[k] = v |
| + except ValueError: |
| + pass # value too large |
| + return v |
| + else: |
| + def wrapper(self, *args, **kwargs): |
| + c = cache(self) |
| + if c is None: |
| + return method(self, *args, **kwargs) |
| + k = key(self, *args, **kwargs) |
| + try: |
| + with lock(self): |
| + return c[k] |
| + except KeyError: |
| + pass # key not found |
| + v = method(self, *args, **kwargs) |
| + try: |
| + with lock(self): |
| + c[k] = v |
| + except ValueError: |
| + pass # value too large |
| + return v |
| + return _update_wrapper(wrapper, method) |
| + return decorator |