-
Notifications
You must be signed in to change notification settings - Fork 2
/
bucket.go
executable file
·73 lines (66 loc) · 1.2 KB
/
bucket.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
package roc
import (
"sync"
"time"
)
// Bucket is a piece of cache.
type Bucket struct {
coll sync.Map
}
// NewBucket returns a bucket.
func NewBucket() (*Bucket, error) {
b := new(Bucket)
return b, nil
}
// Get returns a corresponding value.
func (b *Bucket) Get(key string) (interface{}, error) {
value, hit := b.coll.Load(key)
if !hit {
return nil, ErrMiss
}
u, ok := value.(*Unit)
if !ok {
return nil, ErrMiss
}
if u.Expire() {
return nil, ErrMiss
}
return u.Data, nil
}
// Set sets a value for a key.
func (b *Bucket) Set(key string, data interface{}, d time.Duration) error {
value, hit := b.coll.Load(key)
if !hit {
unit := new(Unit)
unit.Key = key
unit.Data = data
unit.ExpirationTime = time.Now().UTC().Add(d)
b.coll.Store(key, unit)
return nil
}
unit, ok := value.(*Unit)
if !ok {
return nil
}
unit.Data = data
unit.ExpirationTime = time.Now().UTC().Add(d)
return nil
}
// Del deletes a key.
func (b *Bucket) Del(key string) {
b.coll.Delete(key)
}
func (b *Bucket) gc() {
b.coll.Range(func(key, value interface{}) (keep bool) {
keep = true
unit, ok := value.(*Unit)
if !ok {
return
}
if !unit.Expire() {
return
}
b.Del(key.(string))
return
})
}