1+ class Node :
2+ def __init__ (self , key , value ):
3+ self .key = key
4+ self .value = value
5+ self .next = None
6+ self .previous = None
7+
8+ class LruCache :
9+ def __init__ (self , limit ):
10+ if limit <= 0 :
11+ raise ValueError
12+
13+ self .limit = limit
14+ self .cache = {}
15+ self .head = None
16+ self .tail = None
17+
18+ def _remove_node (self , node ):
19+ if node .previous is not None :
20+ node .previous .next = node .next
21+ else :
22+ self .head = node .next
23+
24+ if node .next is not None :
25+ node .next .previous = node .previous
26+ else :
27+ self .tail = node .previous
28+
29+ def _add_to_tail (self , node ):
30+ node .next = None
31+ node .previous = self .tail
32+
33+ if self .tail is not None :
34+ self .tail .next = node
35+ else :
36+ self .head = node
37+
38+ self .tail = node
39+
40+ def get (self , key ):
41+ if key not in self .cache :
42+ return None
43+
44+ node = self .cache [key ]
45+
46+ # Move node to the most-recently-used position
47+ if node is not self .tail :
48+ self ._remove_node (node )
49+ self ._add_to_tail (node )
50+
51+ return node .value
52+
53+ def set (self , key , value ):
54+ if key in self .cache :
55+ node = self .cache [key ]
56+ node .value = value
57+
58+ # Updating an item counts as using it
59+ if node is not self .tail :
60+ self ._remove_node (node )
61+ self ._add_to_tail (node )
62+
63+ return
64+
65+ node = Node (key , value )
66+ self .cache [key ] = node
67+ self ._add_to_tail (node )
68+
69+ if len (self .cache ) > self .limit :
70+ lru_node = self .head
71+
72+ self ._remove_node (lru_node )
73+ del self .cache [lru_node .key ]
0 commit comments