diff --git a/CHANGELOG.md b/CHANGELOG.md index 60c1d877..ae257ab7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,10 @@ CHANGELOG ========= +0.53.1 +------ +- Bug fixes and minor improvements + 0.53.0 ------ - Multi-line display diff --git a/src/cache.go b/src/cache.go index 39d4250d..130915db 100644 --- a/src/cache.go +++ b/src/cache.go @@ -22,6 +22,14 @@ func (cc *ChunkCache) Clear() { cc.mutex.Unlock() } +func (cc *ChunkCache) retire(chunk ...*Chunk) { + cc.mutex.Lock() + for _, c := range chunk { + delete(cc.cache, c) + } + cc.mutex.Unlock() +} + // Add adds the list to the cache func (cc *ChunkCache) Add(chunk *Chunk, key string, list []Result) { if len(key) == 0 || !chunk.IsFull() || len(list) > queryCacheMax { diff --git a/src/chunklist.go b/src/chunklist.go index 91177b17..bd98999d 100644 --- a/src/chunklist.go +++ b/src/chunklist.go @@ -16,14 +16,16 @@ type ChunkList struct { chunks []*Chunk mutex sync.Mutex trans ItemBuilder + cache *ChunkCache } // NewChunkList returns a new ChunkList -func NewChunkList(trans ItemBuilder) *ChunkList { +func NewChunkList(cache *ChunkCache, trans ItemBuilder) *ChunkList { return &ChunkList{ chunks: []*Chunk{}, mutex: sync.Mutex{}, - trans: trans} + trans: trans, + cache: cache} } func (c *Chunk) push(trans ItemBuilder, data []byte) bool { @@ -92,7 +94,9 @@ func (cl *ChunkList) Snapshot(tail int) ([]*Chunk, int, bool) { // Copy the chunks to keep ret := make([]*Chunk, numChunks) - copy(ret, cl.chunks[len(cl.chunks)-numChunks:]) + minIndex := len(cl.chunks) - numChunks + cl.cache.retire(cl.chunks[:minIndex]...) + copy(ret, cl.chunks[minIndex:]) for left, i := tail, len(ret)-1; i >= 0; i-- { chunk := ret[i] @@ -104,6 +108,7 @@ func (cl *ChunkList) Snapshot(tail int) ([]*Chunk, int, bool) { newChunk.items[i] = chunk.items[oldCount-left+i] } ret[i] = &newChunk + cl.cache.retire(chunk) break } left -= chunk.count diff --git a/src/chunklist_test.go b/src/chunklist_test.go index c07e4adf..4eff7b94 100644 --- a/src/chunklist_test.go +++ b/src/chunklist_test.go @@ -11,7 +11,7 @@ func TestChunkList(t *testing.T) { // FIXME global sortCriteria = []criterion{byScore, byLength} - cl := NewChunkList(func(item *Item, s []byte) bool { + cl := NewChunkList(NewChunkCache(), func(item *Item, s []byte) bool { item.text = util.ToChars(s) return true }) @@ -80,7 +80,7 @@ func TestChunkList(t *testing.T) { } func TestChunkListTail(t *testing.T) { - cl := NewChunkList(func(item *Item, s []byte) bool { + cl := NewChunkList(NewChunkCache(), func(item *Item, s []byte) bool { item.text = util.ToChars(s) return true }) diff --git a/src/core.go b/src/core.go index f2563a08..a0765221 100644 --- a/src/core.go +++ b/src/core.go @@ -32,10 +32,6 @@ func (r *revision) bumpMinor() { r.minor++ } -func (r revision) equals(other revision) bool { - return r.major == other.major && r.minor == other.minor -} - func (r revision) compatible(other revision) bool { return r.major == other.major } @@ -94,11 +90,12 @@ func Run(opts *Options) (int, error) { } // Chunk list + cache := NewChunkCache() var chunkList *ChunkList var itemIndex int32 header := make([]string, 0, opts.HeaderLines) if len(opts.WithNth) == 0 { - chunkList = NewChunkList(func(item *Item, data []byte) bool { + chunkList = NewChunkList(cache, func(item *Item, data []byte) bool { if len(header) < opts.HeaderLines { header = append(header, byteString(data)) eventBox.Set(EvtHeader, header) @@ -110,7 +107,7 @@ func Run(opts *Options) (int, error) { return true }) } else { - chunkList = NewChunkList(func(item *Item, data []byte) bool { + chunkList = NewChunkList(cache, func(item *Item, data []byte) bool { tokens := Tokenize(byteString(data), opts.Delimiter) if opts.Ansi && opts.Theme.Colored && len(tokens) > 1 { var ansiState *ansiState @@ -170,7 +167,6 @@ func Run(opts *Options) (int, error) { forward = true } } - cache := NewChunkCache() patternCache := make(map[string]*Pattern) patternBuilder := func(runes []rune) *Pattern { return BuildPattern(cache, patternCache, diff --git a/src/matcher.go b/src/matcher.go index 869663fa..4e21f8ca 100644 --- a/src/matcher.go +++ b/src/matcher.go @@ -87,7 +87,9 @@ func (m *Matcher) Loop() { m.sort = request.sort m.revision = request.revision m.mergerCache = make(map[string]*Merger) - m.cache.Clear() + if !request.revision.compatible(m.revision) { + m.cache.Clear() + } cacheCleared = true } @@ -193,7 +195,7 @@ func (m *Matcher) scan(request MatchRequest) (*Merger, bool) { for _, matches := range allMatches { sliceMatches = append(sliceMatches, matches...) } - if m.sort { + if m.sort && request.pattern.sortable { if m.tac { sort.Sort(ByRelevanceTac(sliceMatches)) } else { @@ -234,7 +236,7 @@ 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, minIndex), false + return NewMerger(pattern, partialResults, m.sort && request.pattern.sortable, m.tac, request.revision, minIndex), false } // Reset is called to interrupt/signal the ongoing search @@ -247,7 +249,7 @@ func (m *Matcher) Reset(chunks []*Chunk, patternRunes []rune, cancel bool, final } else { event = reqRetry } - m.reqBox.Set(event, MatchRequest{chunks, pattern, final, sort && pattern.sortable, revision}) + m.reqBox.Set(event, MatchRequest{chunks, pattern, final, sort, revision}) } func (m *Matcher) Stop() { diff --git a/src/terminal.go b/src/terminal.go index 954d0296..128da4e9 100644 --- a/src/terminal.go +++ b/src/terminal.go @@ -1174,7 +1174,7 @@ func (t *Terminal) UpdateList(merger *Merger, triggerResultEvent bool) { } t.progress = 100 t.merger = merger - if !t.revision.equals(newRevision) { + if t.revision != newRevision { if !t.revision.compatible(newRevision) { // Reloaded: clear selection t.selected = make(map[int32]selectedItem)