/
cache.go
129 lines (102 loc) · 2.22 KB
/
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
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
package cache
import (
"gogo-cache/algorithm"
"gogo-cache/link"
"sync"
"time"
)
type Queue interface {
Insert(node link.Node) *link.Node
Update(node *link.Node)
Del(node *link.Node)
Clear()
}
type Cache struct {
sync.Mutex
maxCount int64
nodeMap map[string]*link.Node
queue Queue
}
//insert an item to the cache, replacing any existing item
//If the expire <= 0, the item will never expires
func (cache *Cache) Set(key string, value interface{}, expire time.Duration) {
cache.Lock()
defer cache.Unlock()
nodeMap := cache.nodeMap
queue := cache.queue
newNode := link.New_Node(key, value, expire)
node, ok := nodeMap[key]
if ok {
node.Value = newNode.Value
node.Expire = newNode.Expire
} else {
inserNode := queue.Insert(newNode)
nodeMap[key] = inserNode
}
}
//Get an item from the cache. Returns the item or nil
func (cache *Cache) Get(key string) interface{} {
cache.Lock()
defer cache.Unlock()
nodeMap := cache.nodeMap
queue := cache.queue
node, ok := nodeMap[key]
if !ok {
return nil
}
if node.Expired() {
queue.Del(node)
delete(nodeMap, key)
return nil
}
queue.Update(node)
return node.Value
}
// Delete an item from the cache. Does nothing if the key is not in the cache.
func (cache *Cache) Del(key string) {
cache.Lock()
defer cache.Unlock()
nodeMap := cache.nodeMap
queue := cache.queue
node, ok := nodeMap[key]
if !ok {
return
}
queue.Del(node)
delete(nodeMap, key)
}
//delete all items from cache
func (cache *Cache) Clear() {
cache.Lock()
defer cache.Unlock()
cache.queue.Clear()
cache.nodeMap = map[string]*link.Node{}
}
//Returns the number of items in the cache.
//This may include items that have expired, but have not yet been cleaned up
func (cache *Cache) Count() int64 {
cache.Lock()
defer cache.Unlock()
return int64(len(cache.nodeMap))
}
func New(algName string, maxCount int64) *Cache {
var q Queue
LURQueue := algorithm.New_LRU(maxCount)
LFUQueue := algorithm.New_LFU(maxCount)
FIFOQueue := algorithm.New_LFU(maxCount)
switch algName {
case "LUR":
q = LURQueue
case "LFU":
q = LFUQueue
case "FIFO":
q = FIFOQueue
default:
q = LFUQueue
}
return &Cache{
maxCount: maxCount,
nodeMap: make(map[string]*link.Node),
queue: q,
}
}