Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 6e8c817

Browse files
committed
Refactor calculation of the cache key. Minor code cleanups.
1 parent e80b29b commit 6e8c817

1 file changed

Lines changed: 21 additions & 25 deletions

File tree

Lib/functools.py

Lines changed: 21 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -146,31 +146,35 @@ def lru_cache(maxsize=100, typed=False):
146146
# The internals of the lru_cache are encapsulated for thread safety and
147147
# to allow the implementation to change (including a possible C version).
148148

149-
def decorating_function(user_function,
150-
*, tuple=tuple, sorted=sorted, map=map, len=len, type=type):
149+
def decorating_function(user_function):
151150

152151
cache = dict()
153152
hits = misses = 0
154-
cache_get = cache.get # bound method for fast lookup
155-
kwd_mark = (object(),) # separates positional and keyword args
156-
lock = Lock() # needed because linkedlist isn't threadsafe
157-
root = [] # root of circular doubly linked list
153+
cache_get = cache.get # bound method to lookup key or return None
154+
_len = len # localize the global len() function
155+
kwd_mark = (object(),) # separate positional and keyword args
156+
lock = Lock() # because linkedlist updates aren't threadsafe
157+
root = [] # root of the circular doubly linked list
158158
root[:] = [root, root, None, None] # initialize by pointing to self
159-
PREV, NEXT, KEY, RESULT = 0, 1, 2, 3 # names of link fields
159+
PREV, NEXT, KEY, RESULT = 0, 1, 2, 3 # names for the link fields
160+
161+
def make_key(args, kwds, typed, tuple=tuple, sorted=sorted, type=type):
162+
key = args
163+
if kwds:
164+
sorted_items = tuple(sorted(kwds.items()))
165+
key += kwd_mark + sorted_items
166+
if typed:
167+
key += tuple(type(v) for v in args)
168+
if kwds:
169+
key += tuple(type(v) for k, v in sorted_items)
170+
return key
160171

161172
if maxsize is None:
162173
@wraps(user_function)
163174
def wrapper(*args, **kwds):
164175
# simple caching without ordering or size limit
165176
nonlocal hits, misses
166-
key = args
167-
if kwds:
168-
sorted_items = tuple(sorted(kwds.items()))
169-
key += kwd_mark + sorted_items
170-
if typed:
171-
key += tuple(map(type, args))
172-
if kwds:
173-
key += tuple(type(v) for k, v in sorted_items)
177+
key = make_key(args, kwds, typed) if kwds or typed else args
174178
result = cache_get(key)
175179
if result is not None:
176180
hits += 1
@@ -184,14 +188,7 @@ def wrapper(*args, **kwds):
184188
def wrapper(*args, **kwds):
185189
# size limited caching that tracks accesses by recency
186190
nonlocal hits, misses
187-
key = args
188-
if kwds:
189-
sorted_items = tuple(sorted(kwds.items()))
190-
key += kwd_mark + sorted_items
191-
if typed:
192-
key += tuple(map(type, args))
193-
if kwds:
194-
key += tuple(type(v) for k, v in sorted_items)
191+
key = make_key(args, kwds, typed) if kwds or typed else args
195192
with lock:
196193
link = cache_get(key)
197194
if link is not None:
@@ -210,7 +207,7 @@ def wrapper(*args, **kwds):
210207
last = root[PREV]
211208
link = [last, root, key, result]
212209
cache[key] = last[NEXT] = root[PREV] = link
213-
if len(cache) > maxsize:
210+
if _len(cache) > maxsize:
214211
# purge least recently used cache entry
215212
old_prev, old_next, old_key, old_result = root[NEXT]
216213
root[NEXT] = old_next
@@ -229,7 +226,6 @@ def cache_clear():
229226
nonlocal hits, misses, root
230227
with lock:
231228
cache.clear()
232-
root = []
233229
root[:] = [root, root, None, None]
234230
hits = misses = 0
235231

0 commit comments

Comments
 (0)