forked from zhaojh329/rttys
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcache.go
111 lines (89 loc) · 1.76 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
package cache
import (
"runtime"
"sync"
"time"
)
type Item struct {
value interface{}
expiration int64
}
type Cache struct {
items sync.Map
defaultExpiration time.Duration
gcInterval time.Duration
stop chan struct{}
}
// Delete all expired items from the cache.
func (c *Cache) DeleteExpired() {
now := time.Now().UnixNano()
c.items.Range(func(key, value interface{}) bool {
if value := value.(*Item); value.expiration > 0 && now > value.expiration {
c.items.Delete(key)
}
return true
})
}
func (c *Cache) gcLoop() {
ticker := time.NewTicker(c.gcInterval)
for {
select {
case <-ticker.C:
c.DeleteExpired()
case <-c.stop:
ticker.Stop()
return
}
}
}
func New(defaultExpiration, gcInterval time.Duration) *Cache {
c := &Cache{
defaultExpiration: defaultExpiration,
gcInterval: gcInterval,
stop: make(chan struct{}),
}
go c.gcLoop()
runtime.SetFinalizer(c, func(c *Cache) {
c.stop <- struct{}{}
})
return c
}
func (c *Cache) Active(key interface{}, d time.Duration) {
v, ok := c.items.Load(key)
if ok {
v := v.(*Item)
var e int64
if d == 0 {
d = c.defaultExpiration
}
if d > 0 {
e = time.Now().Add(d).UnixNano()
}
v.expiration = e
}
}
func (c *Cache) Set(key, value interface{}, d time.Duration) {
var e int64
if d == 0 {
d = c.defaultExpiration
}
if d > 0 {
e = time.Now().Add(d).UnixNano()
}
c.items.Store(key, &Item{value, e})
}
func (c *Cache) Get(key interface{}) (interface{}, bool) {
v, ok := c.items.Load(key)
if ok {
v := v.(*Item)
return v.value, true
}
return nil, false
}
func (c *Cache) Del(key interface{}) {
c.items.Delete(key)
}
func (c *Cache) Have(key string) bool {
_, ok := c.items.Load(key)
return ok
}