-
Notifications
You must be signed in to change notification settings - Fork 16
/
route_cache.go
111 lines (88 loc) · 2.08 KB
/
route_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
package rux
import (
"container/list"
"sync"
)
/*************************************************************
* Route Caches TODO move to extends.go
*************************************************************/
// cacheNode struct
type cacheNode struct {
Key string
Value *Route
}
// cachedRoutes struct
type cachedRoutes struct {
size int
list *list.List
lock *sync.RWMutex
hashMap map[string]*list.Element
}
// NewCachedRoutes Get Cache pointer
func NewCachedRoutes(size int) *cachedRoutes {
return &cachedRoutes{
size: size,
list: list.New(),
lock: new(sync.RWMutex),
hashMap: make(map[string]*list.Element),
}
}
// Len cache len
func (c *cachedRoutes) Len() int {
c.lock.RLock()
defer c.lock.RUnlock()
return c.list.Len()
}
// Set route key and Route
func (c *cachedRoutes) Set(k string, v *Route) bool {
c.lock.Lock()
defer c.lock.Unlock()
// key has been exists, update value
if element, isFound := c.hashMap[k]; isFound {
c.list.MoveToFront(element)
cacheNode := element.Value.(*cacheNode)
// update value
cacheNode.Value = v
return true
}
newElement := c.list.PushFront(&cacheNode{k, v})
c.hashMap[k] = newElement
if c.list.Len() > c.size {
lastElement := c.list.Back()
if lastElement == nil {
return true
}
cacheNode := lastElement.Value.(*cacheNode)
delete(c.hashMap, cacheNode.Key)
c.list.Remove(lastElement)
}
return true
}
// Get cached Route by key
func (c *cachedRoutes) Get(k string) (*Route, bool) {
c.lock.RLock()
defer c.lock.RUnlock()
if element, ok := c.hashMap[k]; ok {
c.list.MoveToFront(element)
cacheNode := element.Value.(*cacheNode)
return cacheNode.Value, true
}
return nil, false
}
// Delete Router by key
func (c *cachedRoutes) Delete(k string) bool {
c.lock.Lock()
defer c.lock.Unlock()
if element, ok := c.hashMap[k]; ok {
cacheNode := element.Value.(*cacheNode)
delete(c.hashMap, cacheNode.Key)
c.list.Remove(element)
return true
}
return false
}
// Has returns true if k is exist in the hashmap.
func (c *cachedRoutes) Has(k string) bool {
_, ok := c.Get(k)
return ok
}