diff options
author | Raymond Hettinger <python@rcn.com> | 2012-03-31 02:15:18 (GMT) |
---|---|---|
committer | Raymond Hettinger <python@rcn.com> | 2012-03-31 02:15:18 (GMT) |
commit | 41eb79a016fce3204041e2f6dfd848e998898b28 (patch) | |
tree | 6243689a28b3e5e59ee8b4cd7e2dea8f2225e6cc /Lib/functools.py | |
parent | 3288e948f3fd6c553576ab92706dfd3b5f66f2fb (diff) | |
download | cpython-41eb79a016fce3204041e2f6dfd848e998898b28.zip cpython-41eb79a016fce3204041e2f6dfd848e998898b28.tar.gz cpython-41eb79a016fce3204041e2f6dfd848e998898b28.tar.bz2 |
No need to create and destroy links when updating a fixed-sized circular queue.
Diffstat (limited to 'Lib/functools.py')
-rw-r--r-- | Lib/functools.py | 27 |
1 files changed, 16 insertions, 11 deletions
diff --git a/Lib/functools.py b/Lib/functools.py index 299e9d8..5cf8f1c 100644 --- a/Lib/functools.py +++ b/Lib/functools.py @@ -219,7 +219,7 @@ def lru_cache(maxsize=100, typed=False): def wrapper(*args, **kwds): # size limited caching that tracks accesses by recency - nonlocal hits, misses + nonlocal root, hits, misses key = make_key(args, kwds, typed) if kwds or typed else args with lock: link = cache_get(key) @@ -236,16 +236,21 @@ def lru_cache(maxsize=100, typed=False): return result result = user_function(*args, **kwds) with lock: - # put result in a new link at the front of the list - last = root[PREV] - link = [last, root, key, result] - cache[key] = last[NEXT] = root[PREV] = link - if _len(cache) > maxsize: - # purge the least recently used cache entry - old_prev, old_next, old_key, old_result = root[NEXT] - root[NEXT] = old_next - old_next[PREV] = root - del cache[old_key] + if _len(cache) < maxsize: + # put result in a new link at the front of the list + last = root[PREV] + link = [last, root, key, result] + cache[key] = last[NEXT] = root[PREV] = link + else: + # use root to store the new key and result + root[KEY] = key + root[RESULT] = result + cache[key] = root + # empty the oldest link and make it the new root + root = root[NEXT] + del cache[root[KEY]] + root[KEY] = None + root[RESULT] = None misses += 1 return result |