summaryrefslogtreecommitdiff
path: root/src/matcher.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/matcher.go')
-rw-r--r--src/matcher.go56
1 files changed, 36 insertions, 20 deletions
diff --git a/src/matcher.go b/src/matcher.go
index 95926fe4..7fd01353 100644
--- a/src/matcher.go
+++ b/src/matcher.go
@@ -19,6 +19,20 @@ type MatchRequest struct {
revision revision
}
+type MatchResult struct {
+ merger *Merger
+ passMerger *Merger
+ cancelled bool
+}
+
+func (mr MatchResult) cacheable() bool {
+ return mr.merger != nil && mr.merger.cacheable()
+}
+
+func (mr MatchResult) final() bool {
+ return mr.merger != nil && mr.merger.final
+}
+
// Matcher is responsible for performing search
type Matcher struct {
cache *ChunkCache
@@ -29,7 +43,7 @@ type Matcher struct {
reqBox *util.EventBox
partitions int
slab []*util.Slab
- mergerCache map[string]*Merger
+ mergerCache map[string]MatchResult
revision revision
}
@@ -51,7 +65,7 @@ func NewMatcher(cache *ChunkCache, patternBuilder func([]rune) *Pattern,
reqBox: util.NewEventBox(),
partitions: partitions,
slab: make([]*util.Slab, partitions),
- mergerCache: make(map[string]*Merger),
+ mergerCache: make(map[string]MatchResult),
revision: revision}
}
@@ -85,7 +99,7 @@ func (m *Matcher) Loop() {
cacheCleared := false
if request.sort != m.sort || request.revision != m.revision {
m.sort = request.sort
- m.mergerCache = make(map[string]*Merger)
+ m.mergerCache = make(map[string]MatchResult)
if !request.revision.compatible(m.revision) {
m.cache.Clear()
}
@@ -95,33 +109,32 @@ func (m *Matcher) Loop() {
// Restart search
patternString := request.pattern.AsString()
- var merger *Merger
- cancelled := false
+ var result MatchResult
count := CountItems(request.chunks)
if !cacheCleared {
if count == prevCount {
// Look up mergerCache
- if cached, found := m.mergerCache[patternString]; found && cached.final == request.final {
- merger = cached
+ if cached, found := m.mergerCache[patternString]; found && cached.final() == request.final {
+ result = cached
}
} else {
// Invalidate mergerCache
prevCount = count
- m.mergerCache = make(map[string]*Merger)
+ m.mergerCache = make(map[string]MatchResult)
}
}
- if merger == nil {
- merger, cancelled = m.scan(request)
+ if result.merger == nil {
+ result = m.scan(request)
}
- if !cancelled {
- if merger.cacheable() {
- m.mergerCache[patternString] = merger
+ if !result.cancelled {
+ if result.cacheable() {
+ m.mergerCache[patternString] = result
}
- merger.final = request.final
- m.eventBox.Set(EvtSearchFin, merger)
+ result.merger.final = request.final
+ m.eventBox.Set(EvtSearchFin, result)
}
}
}
@@ -152,16 +165,18 @@ type partialResult struct {
matches []Result
}
-func (m *Matcher) scan(request MatchRequest) (*Merger, bool) {
+func (m *Matcher) scan(request MatchRequest) MatchResult {
startedAt := time.Now()
numChunks := len(request.chunks)
if numChunks == 0 {
- return EmptyMerger(request.revision), false
+ m := EmptyMerger(request.revision)
+ return MatchResult{m, m, false}
}
pattern := request.pattern
+ passMerger := PassMerger(&request.chunks, m.tac, request.revision)
if pattern.IsEmpty() {
- return PassMerger(&request.chunks, m.tac, request.revision), false
+ return MatchResult{passMerger, passMerger, false}
}
minIndex := request.chunks[0].items[0].Index()
@@ -224,7 +239,7 @@ func (m *Matcher) scan(request MatchRequest) (*Merger, bool) {
}
if m.reqBox.Peek(reqReset) {
- return nil, wait()
+ return MatchResult{nil, nil, wait()}
}
if time.Since(startedAt) > progressMinDuration {
@@ -237,7 +252,8 @@ func (m *Matcher) scan(request MatchRequest) (*Merger, bool) {
partialResult := <-resultChan
partialResults[partialResult.index] = partialResult.matches
}
- return NewMerger(pattern, partialResults, m.sort && request.pattern.sortable, m.tac, request.revision, minIndex, maxIndex), false
+ merger := NewMerger(pattern, partialResults, m.sort && request.pattern.sortable, m.tac, request.revision, minIndex, maxIndex)
+ return MatchResult{merger, passMerger, false}
}
// Reset is called to interrupt/signal the ongoing search