forked from beego/beego
-
Notifications
You must be signed in to change notification settings - Fork 0
/
cache.go
133 lines (119 loc) · 2.45 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
130
131
132
133
package beego
import (
"errors"
"fmt"
"strconv"
"sync"
"time"
)
var (
DefaultEvery int = 60 // 1 minute
)
type BeeItem struct {
val interface{}
Lastaccess time.Time
expired int
}
func (itm *BeeItem) Access() interface{} {
itm.Lastaccess = time.Now()
return itm.val
}
type BeeCache struct {
lock sync.RWMutex
dur time.Duration
items map[string]*BeeItem
Every int // Run an expiration check Every seconds
}
// NewDefaultCache returns a new FileCache with sane defaults.
func NewBeeCache() *BeeCache {
cache := BeeCache{dur: time.Since(time.Now()),
Every: DefaultEvery}
return &cache
}
func (bc *BeeCache) Get(name string) interface{} {
bc.lock.RLock()
defer bc.lock.RUnlock()
itm, ok := bc.items[name]
if !ok {
return nil
}
return itm.Access()
}
func (bc *BeeCache) Put(name string, value interface{}, expired int) error {
bc.lock.Lock()
defer bc.lock.Unlock()
t := BeeItem{val: value, Lastaccess: time.Now(), expired: expired}
if _, ok := bc.items[name]; ok {
return errors.New("the key is exist")
} else {
bc.items[name] = &t
}
return nil
}
func (bc *BeeCache) Delete(name string) (ok bool, err error) {
bc.lock.Lock()
defer bc.lock.Unlock()
if _, ok = bc.items[name]; !ok {
return
}
delete(bc.items, name)
_, valid := bc.items[name]
if valid {
ok = false
}
return
}
// Return all of the item in a BeeCache
func (bc *BeeCache) Items() map[string]*BeeItem {
return bc.items
}
func (bc *BeeCache) IsExist(name string) bool {
bc.lock.RLock()
defer bc.lock.RUnlock()
_, ok := bc.items[name]
return ok
}
// Start activates the file cache; it will
func (bc *BeeCache) Start() error {
dur, err := time.ParseDuration(fmt.Sprintf("%ds", bc.Every))
if err != nil {
return err
}
bc.dur = dur
bc.items = make(map[string]*BeeItem, 0)
go bc.vaccuum()
return nil
}
func (bc *BeeCache) vaccuum() {
if bc.Every < 1 {
return
}
for {
<-time.After(time.Duration(bc.dur))
if bc.items == nil {
return
}
for name, _ := range bc.items {
bc.item_expired(name)
}
}
}
// item_expired returns true if an item is expired.
func (bc *BeeCache) item_expired(name string) bool {
bc.lock.Lock()
defer bc.lock.Unlock()
itm, ok := bc.items[name]
if !ok {
return true
}
dur := time.Now().Sub(itm.Lastaccess)
sec, err := strconv.Atoi(fmt.Sprintf("%0.0f", dur.Seconds()))
if err != nil {
delete(bc.items, name)
return true
} else if sec >= itm.expired {
delete(bc.items, name)
return true
}
return false
}