Simple cache decorator

This commit is contained in:
shortcutme 2019-10-06 03:09:48 +02:00
parent 6eb79ba75e
commit 119e1a9bf0
No known key found for this signature in database
GPG Key ID: 5B63BAE6CB9613AE
3 changed files with 128 additions and 0 deletions

59
src/Test/TestCached.py Normal file
View File

@ -0,0 +1,59 @@
import time
from util import Cached
class CachedObject:
def __init__(self):
self.num_called_add = 0
self.num_called_multiply = 0
self.num_called_none = 0
@Cached(timeout=1)
def calcAdd(self, a, b):
self.num_called_add += 1
return a + b
@Cached(timeout=1)
def calcMultiply(self, a, b):
self.num_called_multiply += 1
return a * b
@Cached(timeout=1)
def none(self):
self.num_called_none += 1
return None
class TestCached:
def testNoneValue(self):
cached_object = CachedObject()
assert cached_object.none() is None
assert cached_object.none() is None
assert cached_object.num_called_none == 1
time.sleep(2)
assert cached_object.none() is None
assert cached_object.num_called_none == 2
def testCall(self):
cached_object = CachedObject()
assert cached_object.calcAdd(1, 2) == 3
assert cached_object.calcAdd(1, 2) == 3
assert cached_object.calcMultiply(1, 2) == 2
assert cached_object.calcMultiply(1, 2) == 2
assert cached_object.num_called_add == 1
assert cached_object.num_called_multiply == 1
assert cached_object.calcAdd(2, 3) == 5
assert cached_object.calcAdd(2, 3) == 5
assert cached_object.num_called_add == 2
assert cached_object.calcAdd(1, 2) == 3
assert cached_object.calcMultiply(2, 3) == 6
assert cached_object.num_called_add == 2
assert cached_object.num_called_multiply == 2
time.sleep(2)
assert cached_object.calcAdd(1, 2) == 3
assert cached_object.num_called_add == 3

68
src/util/Cached.py Normal file
View File

@ -0,0 +1,68 @@
import time
class Cached(object):
def __init__(self, timeout):
self.cache_db = {}
self.timeout = timeout
def __call__(self, func):
def wrapper(*args, **kwargs):
key = "%s %s" % (args, kwargs)
cached_value = None
cache_hit = False
if key in self.cache_db:
cache_hit = True
cached_value, time_cached_end = self.cache_db[key]
if time.time() > time_cached_end:
self.cleanupExpired()
cached_value = None
cache_hit = False
if cache_hit:
return cached_value
else:
cached_value = func(*args, **kwargs)
time_cached_end = time.time() + self.timeout
self.cache_db[key] = (cached_value, time_cached_end)
return cached_value
wrapper.emptyCache = self.emptyCache
return wrapper
def cleanupExpired(self):
for key in list(self.cache_db.keys()):
cached_value, time_cached_end = self.cache_db[key]
if time.time() > time_cached_end:
del(self.cache_db[key])
def emptyCache(self):
num = len(self.cache_db)
self.cache_db.clear()
return num
if __name__ == "__main__":
from gevent import monkey
monkey.patch_all()
@Cached(timeout=2)
def calcAdd(a, b):
print("CalcAdd", a, b)
return a + b
@Cached(timeout=1)
def calcMultiply(a, b):
print("calcMultiply", a, b)
return a * b
for i in range(5):
print("---")
print("Emptied", calcAdd.emptyCache())
assert calcAdd(1, 2) == 3
print("Emptied", calcAdd.emptyCache())
assert calcAdd(1, 2) == 3
assert calcAdd(2, 3) == 5
assert calcMultiply(2, 3) == 6
time.sleep(1)

View File

@ -1,3 +1,4 @@
from .Cached import Cached
from .Event import Event
from .Noparallel import Noparallel
from .Pooled import Pooled