summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRaymond Hettinger <python@rcn.com>2012-06-04 07:21:14 (GMT)
committerRaymond Hettinger <python@rcn.com>2012-06-04 07:21:14 (GMT)
commit0c9050c25db74108d1fa4051bca4d16d2394f826 (patch)
tree9e55b0623273f6006bde87fc2bf11793f84ee26f
parentca75b000695f4d98cc4ee8264734e17c9b05cd63 (diff)
downloadcpython-0c9050c25db74108d1fa4051bca4d16d2394f826.zip
cpython-0c9050c25db74108d1fa4051bca4d16d2394f826.tar.gz
cpython-0c9050c25db74108d1fa4051bca4d16d2394f826.tar.bz2
Separate key creation logic from the sequence class that memoizes its hash value.
-rw-r--r--Lib/functools.py43
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):