-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcache_data.py
74 lines (59 loc) · 1.51 KB
/
cache_data.py
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
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
import time
from functools import wraps
from threading import Thread, Lock
_cache = {}
_mutex = Lock()
_no_data = object()
class _ArgsCache:
def __init__(self, args=(), kwargs={}):
self.args = tuple(args)
self.kwargs = tuple(kwargs.items())
def __eq__(self, value, /):
if not isinstance(value, type(self)):
return False
return self.args == value.args and self.kwargs == value.kwargs
def __hash__(self):
return hash((self.args, self.kwargs))
def _remove_value_later(func, argscache, cache_max):
time.sleep(cache_max)
try:
_mutex.acquire()
del (_cache[func][argscache])
if not _cache[func]:
del (_cache[func])
except KeyError:
pass
finally:
_mutex.release()
def cache_return(cache_max=None):
def deco(func):
@wraps(func)
def overwrite(*args, **kwargs):
argscache = _ArgsCache(args, kwargs)
try:
_mutex.acquire()
_cache.setdefault(func, {})
_cache[func].setdefault(argscache, _no_data)
if _cache[func][argscache] is not _no_data:
return _cache[func][argscache]
finally:
_mutex.release()
ret = func(*args, **kwargs)
try:
_mutex.acquire()
_cache[func][argscache] = ret
if cache_max is not None:
Thread(target=_remove_value_later, args=(func, argscache, cache_max), daemon=True).start()
finally:
_mutex.release()
return ret
overwrite.func = func
return overwrite
return deco
def empty_cache():
_cache.clear()
def empty_function_cache(function):
try:
del(_cache[getattr(function, "func", None)])
except KeyError:
pass