-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathlru_cache.go
88 lines (72 loc) · 1.3 KB
/
lru_cache.go
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
package main
// LRUCache for string->string
// TODO: Currently WIP, its just a map.
type LRUCache struct {
m map[string]LinkedNode
n int
lru *LinkedNode
mru *LinkedNode
}
func CreateCache(capacity int) *LRUCache {
return &LRUCache{
m: make(map[string]LinkedNode, capacity),
n: capacity,
}
}
func (l *LRUCache) Get(k string) (string, bool) {
v, exists := l.pop(k)
if !exists {
return "", false
}
l.Set(k, v)
return v, exists
}
func (l *LRUCache) pop(k string) (string, bool) {
node, exists := l.m[k]
if !exists {
return "", false
}
node.Remove()
return node.v, true
}
func (l *LRUCache) Set(k, v string) {
if len(l.m)+1 > l.n {
l.evictLRU()
}
l.setNewMru(k, v)
l.m[k] = *l.mru
}
func (l *LRUCache) setNewMru(k, v string) {
n := &LinkedNode{
k: k,
v: v,
}
if l.mru != nil {
currMru := l.mru
n.prev = currMru
currMru.next = n
}
l.mru = n
}
func (l *LRUCache) evictLRU() {
currLru := l.lru
if currLru != nil {
l.lru = currLru.next
delete(l.m, currLru.k)
}
}
// LinkedNode structure for the basis of a doubly-linked list.
type LinkedNode struct {
prev *LinkedNode
next *LinkedNode
k, v string
}
// Remove a LinkedNode from its neighbours.
func (n *LinkedNode) Remove() {
if n.prev != nil {
n.prev.next = n.next
}
if n.next != nil {
n.next.prev = n.prev
}
}