lru_cache: Fix key being added to queue even when user_function raises an exception
Also change try/catch to get(key, sentinel) because exceptions are more expensive and misses are common for my use-case
This commit is contained in:
parent
694e39b0c9
commit
c1d5d0befa
@ -185,6 +185,8 @@ class lfu_cache_object(object):
|
|||||||
self.cache = {} # mapping of args to results
|
self.cache = {} # mapping of args to results
|
||||||
self.use_count = Counter() # times each key has been accessed
|
self.use_count = Counter() # times each key has been accessed
|
||||||
self.kwd_mark = object() # separate positional and keyword args
|
self.kwd_mark = object() # separate positional and keyword args
|
||||||
|
self.sentinel = object() # marker for cache.get
|
||||||
|
|
||||||
self.hits = self.misses = 0
|
self.hits = self.misses = 0
|
||||||
self.user_function = user_function
|
self.user_function = user_function
|
||||||
self.maxsize = maxsize
|
self.maxsize = maxsize
|
||||||
@ -196,11 +198,17 @@ class lfu_cache_object(object):
|
|||||||
self.use_count[key] += 1
|
self.use_count[key] += 1
|
||||||
|
|
||||||
# get cache entry or compute if not found
|
# get cache entry or compute if not found
|
||||||
try:
|
result = self.cache.get(key, self.sentinel)
|
||||||
result = self.cache[key]
|
if result is not self.sentinel:
|
||||||
self.hits += 1
|
self.hits += 1
|
||||||
except KeyError:
|
else:
|
||||||
result = self.user_function(*args, **kwds)
|
try:
|
||||||
|
# exception thrown by user_function shouldn't leave cache and use_count inconsistent
|
||||||
|
result = self.user_function(*args, **kwds)
|
||||||
|
except:
|
||||||
|
self.use_count[key] -= 1
|
||||||
|
raise
|
||||||
|
|
||||||
self.cache[key] = result
|
self.cache[key] = result
|
||||||
self.misses += 1
|
self.misses += 1
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user