...
1 package ccache
2
3 import (
4 "container/list"
5 "sync/atomic"
6 "time"
7 )
8
9 type Sized interface {
10 Size() int64
11 }
12
13 type TrackedItem interface {
14 Value() interface{}
15 Release()
16 Expired() bool
17 TTL() time.Duration
18 Expires() time.Time
19 Extend(duration time.Duration)
20 }
21
22 type nilItem struct{}
23
24 func (n *nilItem) Value() interface{} { return nil }
25 func (n *nilItem) Release() {}
26
27 func (i *nilItem) Expired() bool {
28 return true
29 }
30
31 func (i *nilItem) TTL() time.Duration {
32 return time.Minute
33 }
34
35 func (i *nilItem) Expires() time.Time {
36 return time.Time{}
37 }
38
39 func (i *nilItem) Extend(duration time.Duration) {
40 }
41
42 var NilTracked = new(nilItem)
43
44 type Item struct {
45 key string
46 group string
47 promotions int32
48 refCount int32
49 expires int64
50 size int64
51 value interface{}
52 element *list.Element
53 }
54
55 func newItem(key string, value interface{}, expires int64, track bool) *Item {
56 size := int64(1)
57 if sized, ok := value.(Sized); ok {
58 size = sized.Size()
59 }
60 item := &Item{
61 key: key,
62 value: value,
63 promotions: 0,
64 size: size,
65 expires: expires,
66 }
67 if track {
68 item.refCount = 1
69 }
70 return item
71 }
72
73 func (i *Item) shouldPromote(getsPerPromote int32) bool {
74 i.promotions += 1
75 return i.promotions == getsPerPromote
76 }
77
78 func (i *Item) Value() interface{} {
79 return i.value
80 }
81
82 func (i *Item) track() {
83 atomic.AddInt32(&i.refCount, 1)
84 }
85
86 func (i *Item) Release() {
87 atomic.AddInt32(&i.refCount, -1)
88 }
89
90 func (i *Item) Expired() bool {
91 expires := atomic.LoadInt64(&i.expires)
92 return expires < time.Now().UnixNano()
93 }
94
95 func (i *Item) TTL() time.Duration {
96 expires := atomic.LoadInt64(&i.expires)
97 return time.Nanosecond * time.Duration(expires-time.Now().UnixNano())
98 }
99
100 func (i *Item) Expires() time.Time {
101 expires := atomic.LoadInt64(&i.expires)
102 return time.Unix(0, expires)
103 }
104
105 func (i *Item) Extend(duration time.Duration) {
106 atomic.StoreInt64(&i.expires, time.Now().Add(duration).UnixNano())
107 }
108
View as plain text