-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathlrucache.py
115 lines (87 loc) · 2.53 KB
/
lrucache.py
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
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
# -*- coding:utf-8 -*-
import threading
class CacheNode(object):
def __init__(self, key=None, value=None):
self.prev = None
self.next = None
self.key = key
self.value = value
def escape(self):
self.prev.next = self.next
self.next.prev = self.prev
self.prev = None
self.next = None
def link(self, node):
self.next = node
node.prev = self
class LruCache(object):
def __init__(self, item_limit):
self.item_limit = item_limit
self.virtual_head = CacheNode()
self.virtual_tail = CacheNode()
self.virtual_head.link(self.virtual_tail)
self.cache = {}
self.lock = threading.Lock()
def set(self, key, value):
if self.item_limit <= 0:
return
with self.lock:
if key in self.cache:
node = self.cache[key]
node.escape()
self.__set_head(node)
node.value = value
else:
if len(self.cache) >= self.item_limit:
node = self.virtual_tail.prev
node.escape()
self.cache.pop(node.key)
node = CacheNode(key, value)
self.__set_head(node)
self.cache[key] = node
def get(self, key, default=None):
with self.lock:
if key in self.cache:
node = self.cache[key]
node.escape()
self.__set_head(node)
return node.value
else:
return default
def __set_head(self, node):
old_head = self.virtual_head.next
self.virtual_head.link(node)
node.link(old_head)
def __repr__(self):
ret = []
ret.append('cache:')
for key, node in self.cache.items():
ret.append(' %r => %r' % (key, node.value))
ret.append('queue:')
node = self.virtual_head.next
while node != self.virtual_tail:
ret.append(' %r => %r' % (node.key, node.value))
node = node.next
ret.append('--')
return '\n'.join(ret)
def main():
lru = LruCache(4)
lru.set(1, 'one')
lru.set(2, 'two')
lru.set(3, 'three')
print lru
lru.set(2, 'TWO')
print lru
lru.set(4, 'four')
print lru
lru.set(5, 'five')
print lru
lru.set(5, 'FIVE')
print lru
lru.set(3, '??')
print lru
ret = lru.get(2)
print ret
print lru
if __name__ == '__main__':
main()