diff options
Diffstat (limited to 'src/matcher.go')
| -rw-r--r-- | src/matcher.go | 56 |
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 |
