blob: cedbe45e69c40061cac0358dab30febc4d6860a4 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
|
# vim:fileencoding=utf-8:noet
from __future__ import (unicode_literals, division, absolute_import, print_function)
from functools import wraps
from powerline.lib.monotonic import monotonic
def default_cache_key(**kwargs):
return frozenset(kwargs.items())
class memoize(object):
'''Memoization decorator with timeout.'''
def __init__(self, timeout, cache_key=default_cache_key, cache_reg_func=None):
self.timeout = timeout
self.cache_key = cache_key
self.cache = {}
self.cache_reg_func = cache_reg_func
def __call__(self, func):
@wraps(func)
def decorated_function(**kwargs):
if self.cache_reg_func:
self.cache_reg_func(self.cache)
self.cache_reg_func = None
key = self.cache_key(**kwargs)
try:
cached = self.cache.get(key, None)
except TypeError:
return func(**kwargs)
# Handle case when time() appears to be less then cached['time'] due
# to clock updates. Not applicable for monotonic clock, but this
# case is currently rare.
if cached is None or not (cached['time'] < monotonic() < cached['time'] + self.timeout):
cached = self.cache[key] = {
'result': func(**kwargs),
'time': monotonic(),
}
return cached['result']
return decorated_function
|