diff options
Diffstat (limited to 'src/matcher.go')
-rw-r--r-- | src/matcher.go | 55 |
1 files changed, 36 insertions, 19 deletions
diff --git a/src/matcher.go b/src/matcher.go index b9288bb6..869663fa 100644 --- a/src/matcher.go +++ b/src/matcher.go @@ -16,11 +16,12 @@ type MatchRequest struct { pattern *Pattern final bool sort bool - revision int + revision revision } // Matcher is responsible for performing search type Matcher struct { + cache *ChunkCache patternBuilder func([]rune) *Pattern sort bool tac bool @@ -29,7 +30,7 @@ type Matcher struct { partitions int slab []*util.Slab mergerCache map[string]*Merger - revision int + revision revision } const ( @@ -38,10 +39,11 @@ const ( ) // NewMatcher returns a new Matcher -func NewMatcher(patternBuilder func([]rune) *Pattern, - sort bool, tac bool, eventBox *util.EventBox, revision int) *Matcher { +func NewMatcher(cache *ChunkCache, patternBuilder func([]rune) *Pattern, + sort bool, tac bool, eventBox *util.EventBox, revision revision) *Matcher { partitions := util.Min(numPartitionsMultiplier*runtime.NumCPU(), maxPartitions) return &Matcher{ + cache: cache, patternBuilder: patternBuilder, sort: sort, tac: tac, @@ -60,8 +62,13 @@ func (m *Matcher) Loop() { for { var request MatchRequest + stop := false m.reqBox.Wait(func(events *util.Events) { - for _, val := range *events { + for t, val := range *events { + if t == reqQuit { + stop = true + return + } switch val := val.(type) { case MatchRequest: request = val @@ -71,12 +78,17 @@ func (m *Matcher) Loop() { } events.Clear() }) + if stop { + break + } + cacheCleared := false if request.sort != m.sort || request.revision != m.revision { m.sort = request.sort m.revision = request.revision m.mergerCache = make(map[string]*Merger) - clearChunkCache() + m.cache.Clear() + cacheCleared = true } // Restart search @@ -85,20 +97,20 @@ func (m *Matcher) Loop() { cancelled := false count := CountItems(request.chunks) - foundCache := false - if count == prevCount { - // Look up mergerCache - if cached, found := m.mergerCache[patternString]; found { - foundCache = true - merger = cached + if !cacheCleared { + if count == prevCount { + // Look up mergerCache + if cached, found := m.mergerCache[patternString]; found { + merger = cached + } + } else { + // Invalidate mergerCache + prevCount = count + m.mergerCache = make(map[string]*Merger) } - } else { - // Invalidate mergerCache - prevCount = count - m.mergerCache = make(map[string]*Merger) } - if !foundCache { + if merger == nil { merger, cancelled = m.scan(request) } @@ -150,6 +162,7 @@ func (m *Matcher) scan(request MatchRequest) (*Merger, bool) { return PassMerger(&request.chunks, m.tac, request.revision), false } + minIndex := request.chunks[0].items[0].Index() cancelled := util.NewAtomicBool(false) slices := m.sliceChunks(request.chunks) @@ -221,11 +234,11 @@ func (m *Matcher) scan(request MatchRequest) (*Merger, bool) { partialResult := <-resultChan partialResults[partialResult.index] = partialResult.matches } - return NewMerger(pattern, partialResults, m.sort, m.tac, request.revision), false + return NewMerger(pattern, partialResults, m.sort, m.tac, request.revision, minIndex), false } // Reset is called to interrupt/signal the ongoing search -func (m *Matcher) Reset(chunks []*Chunk, patternRunes []rune, cancel bool, final bool, sort bool, revision int) { +func (m *Matcher) Reset(chunks []*Chunk, patternRunes []rune, cancel bool, final bool, sort bool, revision revision) { pattern := m.patternBuilder(patternRunes) var event util.EventType @@ -236,3 +249,7 @@ func (m *Matcher) Reset(chunks []*Chunk, patternRunes []rune, cancel bool, final } m.reqBox.Set(event, MatchRequest{chunks, pattern, final, sort && pattern.sortable, revision}) } + +func (m *Matcher) Stop() { + m.reqBox.Set(reqQuit, nil) +} |