Allow @cached-wrapped functions to have a prefill method for setting entries
This commit is contained in:
parent
4631b737fd
commit
e76d485e29
|
@ -48,24 +48,30 @@ def cached(max_entries=1000):
|
|||
|
||||
The wrapped function has an additional member, a callable called
|
||||
"invalidate". This can be used to remove individual entries from the cache.
|
||||
|
||||
The wrapped function has another additional callable, called "prefill",
|
||||
which can be used to insert values into the cache specifically, without
|
||||
calling the calculation function.
|
||||
"""
|
||||
def wrap(orig):
|
||||
cache = {}
|
||||
|
||||
def prefill(key, value):
|
||||
while len(cache) > max_entries:
|
||||
# TODO(paul): This feels too biased. However, a random index
|
||||
# would be a bit inefficient, walking the list of keys just
|
||||
# to ignore most of them?
|
||||
del cache[cache.keys()[0]]
|
||||
|
||||
cache[key] = value
|
||||
|
||||
@defer.inlineCallbacks
|
||||
def wrapped(self, key):
|
||||
if key in cache:
|
||||
defer.returnValue(cache[key])
|
||||
|
||||
ret = yield orig(self, key)
|
||||
|
||||
while len(cache) > max_entries:
|
||||
# TODO(paul): This feels too biased. However, a random index
|
||||
# would be a bit inefficient, walking the list of keys just
|
||||
# to ignore most of them?
|
||||
del cache[cache.keys()[0]]
|
||||
|
||||
cache[key] = ret;
|
||||
prefill(key, ret)
|
||||
defer.returnValue(ret)
|
||||
|
||||
def invalidate(key):
|
||||
|
@ -73,6 +79,7 @@ def cached(max_entries=1000):
|
|||
del cache[key]
|
||||
|
||||
wrapped.invalidate = invalidate
|
||||
wrapped.prefill = prefill
|
||||
return wrapped
|
||||
|
||||
return wrap
|
||||
|
|
|
@ -87,3 +87,17 @@ class CacheDecoratorTestCase(unittest.TestCase):
|
|||
|
||||
self.assertTrue(callcount[0] >= 14,
|
||||
msg="Expected callcount >= 14, got %d" % (callcount[0]))
|
||||
|
||||
@defer.inlineCallbacks
|
||||
def test_prefill(self):
|
||||
callcount = [0]
|
||||
|
||||
@cached()
|
||||
def func(self, key):
|
||||
callcount[0] += 1
|
||||
return key
|
||||
|
||||
func.prefill("foo", 123)
|
||||
|
||||
self.assertEquals((yield func(self, "foo")), 123)
|
||||
self.assertEquals(callcount[0], 0)
|
||||
|
|
Loading…
Reference in New Issue