diff options
author | Raymond Hettinger <python@rcn.com> | 2012-05-01 03:48:55 (GMT) |
---|---|---|
committer | Raymond Hettinger <python@rcn.com> | 2012-05-01 03:48:55 (GMT) |
commit | 018b4fbb9bab5d7aed513ee04845f25cd702e413 (patch) | |
tree | 2a6b27eeccb67e57baef8d1acc2e7290ad679857 /Lib/functools.py | |
parent | 417c3848d5a594941ca19c73790f5339a1eebcb9 (diff) | |
download | cpython-018b4fbb9bab5d7aed513ee04845f25cd702e413.zip cpython-018b4fbb9bab5d7aed513ee04845f25cd702e413.tar.gz cpython-018b4fbb9bab5d7aed513ee04845f25cd702e413.tar.bz2 |
Use a flag to indicate when the circular queue is fully populated and stable.
Diffstat (limited to 'Lib/functools.py')
-rw-r--r-- | Lib/functools.py | 21 |
1 files changed, 12 insertions, 9 deletions
diff --git a/Lib/functools.py b/Lib/functools.py index 8206c4a..66af5f3 100644 --- a/Lib/functools.py +++ b/Lib/functools.py @@ -176,6 +176,7 @@ def lru_cache(maxsize=100, typed=False): cache = {} hits = misses = currsize = 0 + full = False cache_get = cache.get # bound method to lookup a key or return None lock = Lock() # because linkedlist updates aren't threadsafe root = [] # root of the circular doubly linked list @@ -224,7 +225,7 @@ def lru_cache(maxsize=100, typed=False): def wrapper(*args, **kwds): # size limited caching that tracks accesses by recency - nonlocal root, hits, misses, currsize + nonlocal root, hits, misses, currsize, full key = make_key(args, kwds, typed) if kwds or typed else args with lock: link = cache_get(key) @@ -247,13 +248,7 @@ def lru_cache(maxsize=100, typed=False): # update is already done, we need only return the # computed result and update the count of misses. pass - if currsize < maxsize: - # put result in a new link at the front of the queue - last = root[PREV] - link = [last, root, key, result] - cache[key] = last[NEXT] = root[PREV] = link - currsize += 1 - else: + elif full: # use root to store the new key and result root[KEY] = key root[RESULT] = result @@ -262,6 +257,13 @@ def lru_cache(maxsize=100, typed=False): root = root[NEXT] del cache[root[KEY]] root[KEY] = root[RESULT] = None + else: + # put result in a new link at the front of the queue + last = root[PREV] + link = [last, root, key, result] + cache[key] = last[NEXT] = root[PREV] = link + currsize += 1 + full = (currsize == maxsize) misses += 1 return result @@ -272,11 +274,12 @@ def lru_cache(maxsize=100, typed=False): def cache_clear(): """Clear the cache and cache statistics""" - nonlocal hits, misses, currsize + nonlocal hits, misses, currsize, full with lock: cache.clear() root[:] = [root, root, None, None] hits = misses = currsize = 0 + full = False wrapper.cache_info = cache_info wrapper.cache_clear = cache_clear |