/
mgccache.go
122 lines (98 loc) · 1.89 KB
/
mgccache.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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
package golang
import (
"go/types"
"margo.sh/mgpf"
"regexp"
"sync"
"time"
)
// mgcCacheKey is the key used for caching package imports
type mgcCacheKey struct {
gsuPkgInfo
// Source indicates whether the package was imported from source code
Source bool
}
func (mck mgcCacheKey) fallback() mgcCacheKey {
fbk := mck
fbk.Source = !fbk.Source
return fbk
}
type mgcCacheEnt struct {
Key mgcCacheKey
Pkg *types.Package
Dur time.Duration
}
type mgcCache struct {
sync.RWMutex
m map[mgcCacheKey]mgcCacheEnt
}
func (mc *mgcCache) get(k mgcCacheKey) (mgcCacheEnt, bool) {
mc.RLock()
defer mc.RUnlock()
e, ok := mc.m[k]
if !ok {
mctl.dbgf("cache.miss: %+v\n", k)
}
return e, ok
}
func (mc *mgcCache) put(e mgcCacheEnt) {
if !e.Pkg.Complete() {
mctl.dbgf("cache.put: not storing %+v, it's incomplete\n", e.Key)
return
}
mc.Lock()
defer mc.Unlock()
mc.m[e.Key] = e
mctl.dbgf("cache.put: %+v %s\n", e.Key, mgpf.D(e.Dur))
}
func (mc *mgcCache) del(k mgcCacheKey) {
mc.Lock()
defer mc.Unlock()
if _, exists := mc.m[k]; !exists {
return
}
delete(mc.m, k)
mctl.dbgf("cache.del: %+v\n", k)
}
func (mc *mgcCache) prune(pats ...*regexp.Regexp) []mgcCacheEnt {
ents := []mgcCacheEnt{}
defer func() {
for _, e := range ents {
mctl.dbgf("cache.prune: %+v\n", e.Key)
}
}()
mc.Lock()
defer mc.Unlock()
for _, e := range mc.m {
for _, pat := range pats {
if pat.MatchString(e.Key.Path) {
ents = append(ents, e)
delete(mc.m, e.Key)
}
}
}
return ents
}
func (mc *mgcCache) size() int {
mc.RLock()
defer mc.RUnlock()
return len(mc.m)
}
func (mc *mgcCache) entries() []mgcCacheEnt {
mc.RLock()
defer mc.RUnlock()
l := make([]mgcCacheEnt, 0, len(mc.m))
for _, e := range mc.m {
l = append(l, e)
}
return l
}
func (mc *mgcCache) forEach(f func(mgcCacheEnt) bool) {
mc.RLock()
defer mc.RUnlock()
for _, e := range mc.m {
if !f(e) {
break
}
}
}