mirror of
https://github.com/junegunn/fzf.git
synced 2025-08-07 23:52:04 -07:00
Less aggressive chunk cache invalidation for --tail
This commit is contained in:
@@ -1,6 +1,10 @@
|
|||||||
CHANGELOG
|
CHANGELOG
|
||||||
=========
|
=========
|
||||||
|
|
||||||
|
0.53.1
|
||||||
|
------
|
||||||
|
- Bug fixes and minor improvements
|
||||||
|
|
||||||
0.53.0
|
0.53.0
|
||||||
------
|
------
|
||||||
- Multi-line display
|
- Multi-line display
|
||||||
|
@@ -22,6 +22,14 @@ func (cc *ChunkCache) Clear() {
|
|||||||
cc.mutex.Unlock()
|
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
|
// Add adds the list to the cache
|
||||||
func (cc *ChunkCache) Add(chunk *Chunk, key string, list []Result) {
|
func (cc *ChunkCache) Add(chunk *Chunk, key string, list []Result) {
|
||||||
if len(key) == 0 || !chunk.IsFull() || len(list) > queryCacheMax {
|
if len(key) == 0 || !chunk.IsFull() || len(list) > queryCacheMax {
|
||||||
|
@@ -16,14 +16,16 @@ type ChunkList struct {
|
|||||||
chunks []*Chunk
|
chunks []*Chunk
|
||||||
mutex sync.Mutex
|
mutex sync.Mutex
|
||||||
trans ItemBuilder
|
trans ItemBuilder
|
||||||
|
cache *ChunkCache
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewChunkList returns a new ChunkList
|
// NewChunkList returns a new ChunkList
|
||||||
func NewChunkList(trans ItemBuilder) *ChunkList {
|
func NewChunkList(cache *ChunkCache, trans ItemBuilder) *ChunkList {
|
||||||
return &ChunkList{
|
return &ChunkList{
|
||||||
chunks: []*Chunk{},
|
chunks: []*Chunk{},
|
||||||
mutex: sync.Mutex{},
|
mutex: sync.Mutex{},
|
||||||
trans: trans}
|
trans: trans,
|
||||||
|
cache: cache}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Chunk) push(trans ItemBuilder, data []byte) bool {
|
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
|
// Copy the chunks to keep
|
||||||
ret := make([]*Chunk, numChunks)
|
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-- {
|
for left, i := tail, len(ret)-1; i >= 0; i-- {
|
||||||
chunk := ret[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]
|
newChunk.items[i] = chunk.items[oldCount-left+i]
|
||||||
}
|
}
|
||||||
ret[i] = &newChunk
|
ret[i] = &newChunk
|
||||||
|
cl.cache.retire(chunk)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
left -= chunk.count
|
left -= chunk.count
|
||||||
|
@@ -11,7 +11,7 @@ func TestChunkList(t *testing.T) {
|
|||||||
// FIXME global
|
// FIXME global
|
||||||
sortCriteria = []criterion{byScore, byLength}
|
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)
|
item.text = util.ToChars(s)
|
||||||
return true
|
return true
|
||||||
})
|
})
|
||||||
@@ -80,7 +80,7 @@ func TestChunkList(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestChunkListTail(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)
|
item.text = util.ToChars(s)
|
||||||
return true
|
return true
|
||||||
})
|
})
|
||||||
|
10
src/core.go
10
src/core.go
@@ -32,10 +32,6 @@ func (r *revision) bumpMinor() {
|
|||||||
r.minor++
|
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 {
|
func (r revision) compatible(other revision) bool {
|
||||||
return r.major == other.major
|
return r.major == other.major
|
||||||
}
|
}
|
||||||
@@ -94,11 +90,12 @@ func Run(opts *Options) (int, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Chunk list
|
// Chunk list
|
||||||
|
cache := NewChunkCache()
|
||||||
var chunkList *ChunkList
|
var chunkList *ChunkList
|
||||||
var itemIndex int32
|
var itemIndex int32
|
||||||
header := make([]string, 0, opts.HeaderLines)
|
header := make([]string, 0, opts.HeaderLines)
|
||||||
if len(opts.WithNth) == 0 {
|
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 {
|
if len(header) < opts.HeaderLines {
|
||||||
header = append(header, byteString(data))
|
header = append(header, byteString(data))
|
||||||
eventBox.Set(EvtHeader, header)
|
eventBox.Set(EvtHeader, header)
|
||||||
@@ -110,7 +107,7 @@ func Run(opts *Options) (int, error) {
|
|||||||
return true
|
return true
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
chunkList = NewChunkList(func(item *Item, data []byte) bool {
|
chunkList = NewChunkList(cache, func(item *Item, data []byte) bool {
|
||||||
tokens := Tokenize(byteString(data), opts.Delimiter)
|
tokens := Tokenize(byteString(data), opts.Delimiter)
|
||||||
if opts.Ansi && opts.Theme.Colored && len(tokens) > 1 {
|
if opts.Ansi && opts.Theme.Colored && len(tokens) > 1 {
|
||||||
var ansiState *ansiState
|
var ansiState *ansiState
|
||||||
@@ -170,7 +167,6 @@ func Run(opts *Options) (int, error) {
|
|||||||
forward = true
|
forward = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cache := NewChunkCache()
|
|
||||||
patternCache := make(map[string]*Pattern)
|
patternCache := make(map[string]*Pattern)
|
||||||
patternBuilder := func(runes []rune) *Pattern {
|
patternBuilder := func(runes []rune) *Pattern {
|
||||||
return BuildPattern(cache, patternCache,
|
return BuildPattern(cache, patternCache,
|
||||||
|
@@ -87,7 +87,9 @@ func (m *Matcher) Loop() {
|
|||||||
m.sort = request.sort
|
m.sort = request.sort
|
||||||
m.revision = request.revision
|
m.revision = request.revision
|
||||||
m.mergerCache = make(map[string]*Merger)
|
m.mergerCache = make(map[string]*Merger)
|
||||||
m.cache.Clear()
|
if !request.revision.compatible(m.revision) {
|
||||||
|
m.cache.Clear()
|
||||||
|
}
|
||||||
cacheCleared = true
|
cacheCleared = true
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -193,7 +195,7 @@ func (m *Matcher) scan(request MatchRequest) (*Merger, bool) {
|
|||||||
for _, matches := range allMatches {
|
for _, matches := range allMatches {
|
||||||
sliceMatches = append(sliceMatches, matches...)
|
sliceMatches = append(sliceMatches, matches...)
|
||||||
}
|
}
|
||||||
if m.sort {
|
if m.sort && request.pattern.sortable {
|
||||||
if m.tac {
|
if m.tac {
|
||||||
sort.Sort(ByRelevanceTac(sliceMatches))
|
sort.Sort(ByRelevanceTac(sliceMatches))
|
||||||
} else {
|
} else {
|
||||||
@@ -234,7 +236,7 @@ func (m *Matcher) scan(request MatchRequest) (*Merger, bool) {
|
|||||||
partialResult := <-resultChan
|
partialResult := <-resultChan
|
||||||
partialResults[partialResult.index] = partialResult.matches
|
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
|
// 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 {
|
} else {
|
||||||
event = reqRetry
|
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() {
|
func (m *Matcher) Stop() {
|
||||||
|
@@ -1174,7 +1174,7 @@ func (t *Terminal) UpdateList(merger *Merger, triggerResultEvent bool) {
|
|||||||
}
|
}
|
||||||
t.progress = 100
|
t.progress = 100
|
||||||
t.merger = merger
|
t.merger = merger
|
||||||
if !t.revision.equals(newRevision) {
|
if t.revision != newRevision {
|
||||||
if !t.revision.compatible(newRevision) {
|
if !t.revision.compatible(newRevision) {
|
||||||
// Reloaded: clear selection
|
// Reloaded: clear selection
|
||||||
t.selected = make(map[int32]selectedItem)
|
t.selected = make(map[int32]selectedItem)
|
||||||
|
Reference in New Issue
Block a user