forked from sourcegraph/srclib
/
tree_stores.go
73 lines (65 loc) · 2.08 KB
/
tree_stores.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
package store
// scopeTrees returns a list of commit IDs that are matched by the
// filters. If potentially all commits could match, or if enough
// commits could potentially match that it would probably be cheaper
// to iterate through all of them, then a nil slice is returned. If
// none match, an empty slice is returned.
//
// scopeTrees is used to select which TreeStores to query.
//
// TODO(sqs): return an error if the filters are mutually exclusive?
func scopeTrees(filters []interface{}) ([]string, error) {
commitIDs := map[string]struct{}{}
everHadAny := false // whether unitIDs ever contained any commitIDs
for _, f := range filters {
switch f := f.(type) {
case ByCommitIDsFilter:
if len(commitIDs) == 0 && !everHadAny {
everHadAny = true
for _, c := range f.ByCommitIDs() {
commitIDs[c] = struct{}{}
}
} else {
// Intersect.
newCommitIDs := make(map[string]struct{}, (len(commitIDs)+len(f.ByCommitIDs()))/2)
for _, c := range f.ByCommitIDs() {
if _, present := commitIDs[c]; present {
newCommitIDs[c] = struct{}{}
}
}
commitIDs = newCommitIDs
}
}
}
if len(commitIDs) == 0 && !everHadAny {
// No unit scoping filters were present, so scope includes
// potentially all commitIDs.
return nil, nil
}
ids := make([]string, 0, len(commitIDs))
for commitID := range commitIDs {
ids = append(ids, commitID)
}
return ids, nil
}
// A treeStoreOpener opens the TreeStore for the specified tree.
type treeStoreOpener interface {
openTreeStore(commitID string) TreeStore
openAllTreeStores() (map[string]TreeStore, error)
}
// openCommitstores is a helper func that calls o.openTreeStore for
// each tree returned by scopeTrees(filters...).
func openTreeStores(o treeStoreOpener, filters interface{}) (map[string]TreeStore, error) {
commitIDs, err := scopeTrees(storeFilters(filters))
if err != nil {
return nil, err
}
if commitIDs == nil {
return o.openAllTreeStores()
}
tss := make(map[string]TreeStore, len(commitIDs))
for _, commitID := range commitIDs {
tss[commitID] = o.openTreeStore(commitID)
}
return tss, nil
}