From: Raymond Hettinger Date: Tue, 1 May 2012 03:48:55 +0000 (-0700) Subject: Use a flag to indicate when the circular queue is fully populated and stable. X-Git-Tag: v3.3.0a3~10 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=018b4fbb9bab5d7aed513ee04845f25cd702e413;p=python Use a flag to indicate when the circular queue is fully populated and stable. --- diff --git a/Lib/functools.py b/Lib/functools.py index 8206c4a222..66af5f3679 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