diff options
author | Raymond Hettinger <python@rcn.com> | 2012-06-04 00:21:14 -0700 |
---|---|---|
committer | Raymond Hettinger <python@rcn.com> | 2012-06-04 00:21:14 -0700 |
commit | 28238b5272548905b5959afd9416fef2aac8e8fe (patch) | |
tree | ef2ee317307226fa000dd2012b70cf702e2fdf90 /Lib/functools.py | |
parent | f15bbf24e1c068382c6ea857f0217d83259702e3 (diff) | |
download | cpython-28238b5272548905b5959afd9416fef2aac8e8fe.tar.gz |
Separate key creation logic from the sequence class that memoizes its hash value.
Diffstat (limited to 'Lib/functools.py')
-rw-r--r-- | Lib/functools.py | 43 |
1 files changed, 24 insertions, 19 deletions
diff --git a/Lib/functools.py b/Lib/functools.py index 9f024f14d7..226a46eb21 100644 --- a/Lib/functools.py +++ b/Lib/functools.py @@ -142,30 +142,35 @@ except ImportError: _CacheInfo = namedtuple("CacheInfo", ["hits", "misses", "maxsize", "currsize"]) -class _CacheKey(list): - 'Make a cache key from optionally typed positional and keyword arguments' - +class _HashedSeq(list): __slots__ = 'hashvalue' - def __init__(self, args, kwds, typed, - kwd_mark = (object(),), - sorted=sorted, tuple=tuple, type=type, hash=hash): - key = args - if kwds: - sorted_items = sorted(kwds.items()) - key += kwd_mark - for item in sorted_items: - key += item - if typed: - key += tuple(type(v) for v in args) - if kwds: - key += tuple(type(v) for k, v in sorted_items) - self[:] = key - self.hashvalue = hash(key) # so we only have to hash just once + def __init__(self, tup, hash=hash): + self[:] = tup + self.hashvalue = hash(tup) def __hash__(self): return self.hashvalue +def _make_key(args, kwds, typed, + kwd_mark = (object(),), + fasttypes = {int, str, frozenset, type(None)}, + sorted=sorted, tuple=tuple, type=type, len=len): + 'Make a cache key from optionally typed positional and keyword arguments' + key = args + if kwds: + sorted_items = sorted(kwds.items()) + key += kwd_mark + for item in sorted_items: + key += item + if typed: + key += tuple(type(v) for v in args) + if kwds: + key += tuple(type(v) for k, v in sorted_items) + elif len(key) == 1 and type(key[0]) in fasttypes: + return key[0] + return _HashedSeq(key) + def lru_cache(maxsize=128, typed=False): """Least-recently-used cache decorator. @@ -193,7 +198,7 @@ def lru_cache(maxsize=128, typed=False): # Constants shared by all lru cache instances: sentinel = object() # unique object used to signal cache misses - make_key = _CacheKey # build a key from the function arguments + make_key = _make_key # build a key from the function arguments PREV, NEXT, KEY, RESULT = 0, 1, 2, 3 # names for the link fields def decorating_function(user_function): |