1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
|
PREV, NEXT, KEY, VALUE = 0, 1, 2, 3
def lru_cache_4(max_size=128):
root = []
root[:] = root, root, None, None
cache = {}
cache_get = cache.get
cache_len = cache.__len__
def decorator(func):
def wrapper(*args, **kwargs):
nonlocal root
key = make_key(args, kwargs)
link = cache_get(key)
if link is not None:
link_prev, link_next, _, value = link
link_prev[NEXT] = link_next
link_next[PREV] = link_prev
last = root[PREV]
last[NEXT] = root[PREV] = link
link[PREV] = last
link[NEXT] = root
return value
value = func(*args, **kwargs)
if cache_len() >= max_size:
old_root = root
old_root[KEY] = key
old_root[VALUE] = value
root = old_root[NEXT]
old_key = root[KEY]
del cache[old_key]
cache[key] = old_root
root[KEY] = root[VALUE] = None
else:
last = root[PREV]
link = [last, root, key, value]
last[NEXT] = root[PREV] = cache[key] = link
return value
return wrapper
return decorator
|