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 |