Skip to content

Commit 32f3ccf

Browse files
committed
lfu
1 parent e4acd61 commit 32f3ccf

File tree

1 file changed

+63
-0
lines changed

1 file changed

+63
-0
lines changed

docs/15_堆与堆排序/lfu.py

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,66 @@
44
55
这里学习下 LRU(least frequently used),就是当缓存满了之后剔除一个最少使用的 key。
66
"""
7+
from collections import defaultdict, OrderedDict
8+
9+
10+
class Node:
11+
__slots__ = 'key', 'val', 'cnt'
12+
13+
def __init__(self, key, val, cnt=0):
14+
self.key, self.val, self.cnt = key, val, cnt
15+
16+
17+
class LFUCache:
18+
def __init__(self, capacity):
19+
self.capacity = capacity
20+
self.cache = {} # type {key: node}
21+
self.cnt2node = defaultdict(OrderedDict)
22+
self.mincnt = 0
23+
24+
def get(self, key, default=-1):
25+
if key not in self.cache:
26+
return default
27+
28+
node = self.cache[key]
29+
del self.cnt2node[node.cnt][key]
30+
31+
if not self.cnt2node[node.cnt]:
32+
del self.cnt2node[node.cnt]
33+
34+
node.cnt += 1
35+
self.cnt2node[node.cnt][key] = node
36+
37+
if not self.cnt2node[self.mincnt]:
38+
self.mincnt += 1
39+
return node.val
40+
41+
def put(self, key, value):
42+
if key in self.cache:
43+
self.cache[key].val = value
44+
self.get(key)
45+
return
46+
if len(self.cache) >= self.capacity:
47+
pop_key, _pop_node = self.cnt2node[self.mincnt].popitem(last=False)
48+
del self.cache[pop_key]
49+
50+
self.cache[key] = self.cnt2node[1][key] = Node(key, value, 1)
51+
self.mincnt = 1
52+
53+
54+
def test():
55+
c = LFUCache(2)
56+
c.put(1, 1)
57+
c.put(2, 2)
58+
assert c.get(1) == 1
59+
c.put(3, 3)
60+
assert c.get(2) == -1
61+
assert c.get(3) == 3
62+
c.put(4, 4)
63+
assert c.get(1) == -1
64+
assert c.get(3) == 3
65+
assert c.get(4) == 4
66+
67+
68+
if __name__ == '__main__':
69+
test()

0 commit comments

Comments
 (0)