-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathp_1_LRU_Cache.py
More file actions
129 lines (106 loc) · 4.03 KB
/
p_1_LRU_Cache.py
File metadata and controls
129 lines (106 loc) · 4.03 KB
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
116
117
118
119
120
121
122
123
124
125
126
127
128
129
'''
Least Recently Used Cache
We have briefly discussed caching as part of a practice problem while studying hash maps.
The lookup operation (i.e., get()) and put() / set() is supposed to be fast for a cache memory.
While doing the get() operation, if the entry is found in the cache, it is known as a cache hit.
If, however, the entry is not found, it is known as a cache miss.
When designing a cache, we also place an upper bound on the size of the cache.
If the cache is full and we want to add a new entry to the cache,
we use some criteria to remove an element.
After removing an element, we use the put() operation to insert the new element.
The remove operation should also be fast.
For our first problem, the goal will be to design a data structure known
as a Least Recently Used (LRU) cache.
An LRU cache is a type of cache in which we remove the least recently used entry
when the cache memory reaches its limit.
For the current problem, consider both get and set operations as an use operation.
Your job is to use an appropriate data structure(s) to implement the cache.
In case of a cache hit, your get() operation should return the appropriate value.
In case of a cache miss, your get() should return -1.
While putting an element in the cache, your put() / set() operation must insert the element. If the cache is full, you must write code that removes the least recently used entry first and then insert the element.
All operations must take O(1) time.
For the current problem, you can consider the size of cache = 5.
Here is some boiler plate code and some example test cases to get you started on this problem:
'''
class Node:
def __init__(self, key, value):
self.key = key
self.value = value
self.next = None
self.prev = None
class LRU_Cache:
def __init__(self, capacity):
self.capacity = capacity
self.cache = dict()
self.head = Node(0, 0)
self.tail = Node(0, 0)
self.head.next = self.tail
self.tail.prev = self.head
def get(self, key):
if key in self.cache:
node = self.cache[key]
self._remove(node)
self._add(node)
return node.value
return - 1
def set(self, key, value):
if key in self.cache:
self._remove(self.cache[key])
node = Node(key, value)
self._add(node)
self.cache[key] = node
if len(self.cache) > self.capacity:
node = self.head.next
self._remove(node)
del self.cache[node.key]
def _remove(self, node):
prev_node = node.prev
next_node = node.next
prev_node.next = next_node
next_node.prev = prev_node
def _add(self, node):
prev_node = self.tail.prev
prev_node.next = node
self.tail.prev = node
node.prev = prev_node
node.next = self.tail
our_cache = LRU_Cache(5)
our_cache.set(1, 1)
print('Current Cache: {}'.format(our_cache.cache))
our_cache.set(2, 2)
print('Current Cache: {}'.format(our_cache.cache))
our_cache.set(3, 3)
print('Current Cache: {}'.format(our_cache.cache))
our_cache.set(4, 4)
print('Current Cache: {}'.format(our_cache.cache))
print(our_cache.get(1)) # returns 1
print(our_cache.get(2)) # returns 2
print(our_cache.get(9)) # returns -1 because 9 is not present in the cache
our_cache.set(5, 5)
print(our_cache.cache)
our_cache.set(6, 6)
print(our_cache.cache)
print(our_cache.get(3)) # returns -1 because the cache reached its capacity and
# 3 was the least recently used entry
# Test for cache capacity 0. Should return -1
cache = LRU_Cache(0)
cache.set(1, 1)
assert cache.get(1) == -1
cache.set(2, 2)
assert cache.get(2) == -1
# Test for cache capacity 3
cache = LRU_Cache(3)
cache.set(1, 1)
cache.set(2, 2)
cache.set(3, 3)
assert cache.get(3) == 3
assert cache.get(2) == 2
assert cache.get(1) == 1
# Test for cache capacity 7
cache = LRU_Cache(7)
cache.set(1, 10)
cache.set(2, 20)
cache.set(5, 50)
assert cache.get(5) == 50
assert cache.get(2) == 20
assert cache.get(1) == 10