-
Notifications
You must be signed in to change notification settings - Fork 23
/
Copy pathlru.go
87 lines (77 loc) · 1.33 KB
/
lru.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
package jet
import (
"container/list"
"crypto/sha1"
"database/sql"
"sync"
)
type lru struct {
m sync.Mutex
maxItems int
keys map[string]*list.Element
list *list.List
}
type lruItem struct {
key string
stmt *sql.Stmt
}
func newLru() *lru {
return &lru{
maxItems: 500,
keys: make(map[string]*list.Element),
list: list.New(),
}
}
func (c *lru) get(k string) (*sql.Stmt, bool) {
c.m.Lock()
defer c.m.Unlock()
k = makeKey(k)
e, ok := c.keys[k]
if ok {
return e.Value.(*lruItem).stmt, ok
}
return nil, false
}
func (c *lru) put(k string, stmt *sql.Stmt) {
c.m.Lock()
defer c.m.Unlock()
k = makeKey(k)
e, ok := c.keys[k]
if ok {
c.list.MoveToFront(e)
} else {
c.keys[k] = c.list.PushFront(&lruItem{
key: k,
stmt: stmt,
})
}
c.clean()
}
func (c *lru) del(k string) {
c.m.Lock()
defer c.m.Unlock()
k = makeKey(k)
e, ok := c.keys[k]
if ok {
c.delElem(e)
}
}
func (c *lru) delElem(e *list.Element) {
item := c.list.Remove(e).(*lruItem)
defer item.stmt.Close()
delete(c.keys, item.key)
}
func (c *lru) clean() {
n := c.list.Len() - c.maxItems
if n > 0 {
for i := 0; i < n; i++ {
c.delElem(c.list.Back())
}
}
}
// makeKey hashes the key to save some bytes
func makeKey(k string) string {
buffer := sha1.New()
buffer.Write([]byte(k))
return string(buffer.Sum(nil))
}