forked from GoogleCloudPlatform/gcr-cleaner
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcache.go
72 lines (61 loc) · 1.24 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
package main
import (
"sync"
"time"
)
// timerCache is a Cache implementation that caches items for a configurable
// period of time.
type timerCache struct {
lock sync.RWMutex
data map[string]struct{}
lifetime time.Duration
stopCh chan struct{}
stopped bool
}
func newTimerCache(lifetime time.Duration) *timerCache {
return &timerCache{
data: make(map[string]struct{}),
lifetime: lifetime,
stopCh: make(chan struct{}),
}
}
// Stop stops the cache.
func (c *timerCache) Stop() {
c.lock.Lock()
if !c.stopped {
close(c.stopCh)
c.stopped = true
}
c.lock.Unlock()
}
// Insert adds the item to the cache. If the item already existed in the cache,
// this function returns false.
func (c *timerCache) Insert(s string) bool {
// Read only
c.lock.RLock()
if _, ok := c.data[s]; ok {
c.lock.RUnlock()
return true
}
c.lock.RUnlock()
// Full insert
c.lock.Lock()
if _, ok := c.data[s]; ok {
c.lock.Unlock()
return true
}
c.data[s] = struct{}{}
c.lock.Unlock()
// Start a timeout to delete the item from the cache.
go c.timeout(s)
return false
}
func (c *timerCache) timeout(s string) {
select {
case <-time.After(c.lifetime):
c.lock.Lock()
delete(c.data, s)
c.lock.Unlock()
case <-c.stopCh:
}
}