cache lru

lru

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 lru

//LRU Cache
import (
"container/list"
)

type CacheNode struct {
key interface{}
value interface{}
}

func NewCacheNode(k, v interface{}) *CacheNode {
return &CacheNode{k, v}
}

type Lru struct {
capacity int
dlist *list.List
cacheMap map[interface{}]*list.Element
}

func NewLru(cap int) *Lru {
return &Lru{
capacity: cap,
dlist: list.New(),
cacheMap: make(map[interface{}]*list.Element),
}
}

func (lru *Lru) Size() int {
return lru.dlist.Len()
}

func (lru *Lru) Set(k, v interface{}) error {
if lru.dlist == nil {
return error.New("lrucache need init")
}

//key exist, movetoFront, update value
if pElement, ok := lru.cacheMap[k]; ok {
lru.dlist.MoveToFront(pElement)
pElement.Value.(*CacheNode).Value = v
return nil
}

//not exist
newElement := lru.dlist.PushFront(&CacheNode{k, v})
lru.cacheMap[k] = newElement

if lru.dlist.Len() > lru.capacity {
lastElement := lru.dlist.Back()
if lastElement == nil {
return nil
}

cacheNode := lastElement.Value.(*CacheNode)
delete(lru.cacheMap, cacheNode.key)
lru.dlist.Remove(lastElement)
}
return nil
}

func (lru *Lru) Get(k interface{}) (v interface{}, err error) {
if lru.cacheMap == nil {
return v, errors.New("LRUCache need init")
}

if pElement, ok := lru.cacheMap[k]; ok {
lru.dlist.MoveToFront(pElement)
return pElement.Value.(*CacheNode).Value, nil
}
return v, nil
}

func (lru *LRUCache) Remove(k interface{}) bool {
if lru.cacheMap == nil {
return false
}

if pElement, ok := lru.cacheMap[k]; ok {
cacheNode := pElement.Value.(*CacheNode)
delete(lru.cacheMap, cacheNode.Key)
lru.dlist.Remove(pElement)
return true
}
return false
}