Skip to content

Commit 8fb8600

Browse files
author
Vadym Fedorov
committed
LRU cache solution
1 parent 08168a0 commit 8fb8600

File tree

1 file changed

+85
-0
lines changed

1 file changed

+85
-0
lines changed

lru-cache/solution_test.go

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
package solution
2+
3+
// Source: https://girai.dev/blog/lru-cache-implementation-in-go/
4+
5+
import (
6+
"container/list"
7+
"testing"
8+
)
9+
10+
type LRUCache struct {
11+
cap int // capacity
12+
l *list.List // doubly linked list
13+
m map[int]*list.Element // hash table for checking if list node exists
14+
}
15+
16+
// Pair is the value of a list node.
17+
type ListItem struct {
18+
key int
19+
value int
20+
}
21+
22+
// Constructor initializes a new LRUCache.
23+
func Constructor(capacity int) LRUCache {
24+
return LRUCache{
25+
cap: capacity,
26+
l: new(list.List),
27+
m: make(map[int]*list.Element, capacity),
28+
}
29+
}
30+
31+
// Get a list node from the hash map.
32+
func (c *LRUCache) Get(key int) int {
33+
// check if list node exists
34+
node, ok := c.m[key]
35+
if !ok {
36+
return -1
37+
}
38+
c.l.MoveToFront(node)
39+
return node.Value.(*list.Element).Value.(ListItem).value
40+
}
41+
42+
// Put key and value in the LRUCache
43+
func (c *LRUCache) Put(key int, value int) {
44+
// check if list node exists
45+
if node, ok := c.m[key]; ok {
46+
// move the node to front
47+
c.l.MoveToFront(node)
48+
// update the value of a list node
49+
node.Value.(*list.Element).Value = ListItem{key: key, value: value}
50+
} else {
51+
// delete the last list node if the list is full
52+
if c.l.Len() == c.cap {
53+
// get the key that we want to delete
54+
idx := c.l.Back().Value.(*list.Element).Value.(ListItem).key
55+
// delete the node pointer in the hash map by key
56+
delete(c.m, idx)
57+
// remove the last list node
58+
c.l.Remove(c.l.Back())
59+
}
60+
// initialize a list node
61+
node := &list.Element{
62+
Value: ListItem{
63+
key: key,
64+
value: value,
65+
},
66+
}
67+
// push the new list node into the list
68+
ptr := c.l.PushFront(node)
69+
// save the node pointer in the hash map
70+
c.m[key] = ptr
71+
}
72+
}
73+
74+
func TestLRUCache(t *testing.T) {
75+
cache := Constructor(2)
76+
cache.Put(1, 1)
77+
cache.Put(2, 2)
78+
cache.Get(1) // returns 1
79+
cache.Put(3, 3) // evicts key 2
80+
cache.Get(2) // returns -1 (not found)
81+
cache.Put(4, 4) // evicts key 1
82+
cache.Get(1) // returns -1 (not found)
83+
cache.Get(3) // returns 3
84+
cache.Get(4) // returns 4
85+
}

0 commit comments

Comments
 (0)