...
1 package ccache
2
3 import (
4 "strings"
5 "sync"
6 "time"
7 )
8
9 type bucket struct {
10 sync.RWMutex
11 lookup map[string]*Item
12 }
13
14 func (b *bucket) itemCount() int {
15 b.RLock()
16 defer b.RUnlock()
17 return len(b.lookup)
18 }
19
20 func (b *bucket) forEachFunc(matches func(key string, item *Item) bool) bool {
21 lookup := b.lookup
22 b.RLock()
23 defer b.RUnlock()
24 for key, item := range lookup {
25 if !matches(key, item) {
26 return false
27 }
28 }
29 return true
30 }
31
32 func (b *bucket) get(key string) *Item {
33 b.RLock()
34 defer b.RUnlock()
35 return b.lookup[key]
36 }
37
38 func (b *bucket) set(key string, value interface{}, duration time.Duration, track bool) (*Item, *Item) {
39 expires := time.Now().Add(duration).UnixNano()
40 item := newItem(key, value, expires, track)
41 b.Lock()
42 existing := b.lookup[key]
43 b.lookup[key] = item
44 b.Unlock()
45 return item, existing
46 }
47
48 func (b *bucket) delete(key string) *Item {
49 b.Lock()
50 item := b.lookup[key]
51 delete(b.lookup, key)
52 b.Unlock()
53 return item
54 }
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69 func (b *bucket) deleteFunc(matches func(key string, item *Item) bool, deletables chan *Item) int {
70 lookup := b.lookup
71 items := make([]*Item, 0)
72
73 b.RLock()
74 for key, item := range lookup {
75 if matches(key, item) {
76 deletables <- item
77 items = append(items, item)
78 }
79 }
80 b.RUnlock()
81
82 if len(items) == 0 {
83
84 return 0
85 }
86
87 b.Lock()
88 for _, item := range items {
89 delete(lookup, item.key)
90 }
91 b.Unlock()
92 return len(items)
93 }
94
95 func (b *bucket) deletePrefix(prefix string, deletables chan *Item) int {
96 return b.deleteFunc(func(key string, item *Item) bool {
97 return strings.HasPrefix(key, prefix)
98 }, deletables)
99 }
100
101 func (b *bucket) clear() {
102 b.Lock()
103 b.lookup = make(map[string]*Item)
104 b.Unlock()
105 }
106
View as plain text