diff options
author | Raymond Hettinger <python@rcn.com> | 2012-06-04 07:21:14 (GMT) |
---|---|---|
committer | Raymond Hettinger <python@rcn.com> | 2012-06-04 07:21:14 (GMT) |
commit | 0c9050c25db74108d1fa4051bca4d16d2394f826 (patch) | |
tree | 9e55b0623273f6006bde87fc2bf11793f84ee26f /Lib/functools.py | |
parent | ca75b000695f4d98cc4ee8264734e17c9b05cd63 (diff) | |
download | cpython-0c9050c25db74108d1fa4051bca4d16d2394f826.zip cpython-0c9050c25db74108d1fa4051bca4d16d2394f826.tar.gz cpython-0c9050c25db74108d1fa4051bca4d16d2394f826.tar.bz2 |
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 9f024f1..226a46e 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): |