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