/
dir_entry_cache.go
60 lines (48 loc) · 1.56 KB
/
dir_entry_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
package adbfs
import (
"time"
cache "github.com/pmylund/go-cache"
"golang.org/x/net/trace"
)
const CachePurgeInterval = 5 * time.Minute
type DirEntryLoader func(path string) (*CachedDirEntries, error)
// DirEntryCache is a key-value cache of normalized directory paths to
// slices of *adb.FileEntries.
type DirEntryCache interface {
GetOrLoad(path string, loader DirEntryLoader) (entries *CachedDirEntries, err error, hit bool)
Get(path string) (entries *CachedDirEntries, found bool)
// Removes the entry for path from the cache without blocking on other cache operations.
RemoveEventually(path string)
}
type realDirEntryCache struct {
cache *cache.Cache
eventLog trace.EventLog
}
func NewDirEntryCache(ttl time.Duration) DirEntryCache {
return &realDirEntryCache{
cache: cache.New(ttl, CachePurgeInterval),
eventLog: trace.NewEventLog("DirEntryCache", ""),
}
}
func (c *realDirEntryCache) GetOrLoad(path string, loader DirEntryLoader) (*CachedDirEntries, error, bool) {
if entries, found := c.Get(path); found {
return entries, nil, true
}
entries, err := loader(path)
if err != nil {
return nil, err, false
}
c.cache.Set(path, entries, cache.DefaultExpiration)
return entries, nil, false
}
func (c *realDirEntryCache) Get(path string) (*CachedDirEntries, bool) {
if entries, found := c.cache.Get(path); found {
c.eventLog.Printf("Get(%s) = hit", path)
return entries.(*CachedDirEntries), true
}
c.eventLog.Errorf("Get(%s) = miss", path)
return nil, false
}
func (c *realDirEntryCache) RemoveEventually(path string) {
go c.cache.Delete(path)
}