mirror of
https://github.com/junegunn/fzf
synced 2024-11-14 18:12:53 +00:00
2fe1e28220
I profiled fzf and it turned out that it was spending significant amount of time repeatedly converting character arrays into Unicode codepoints. This commit greatly improves search performance after the initial scan by memoizing the converted results. This commit also addresses the problem of unbounded memory usage of fzf. fzf is a short-lived process that usually processes small input, so it was implemented to cache the intermediate results very aggressively with no notion of cache expiration/eviction. I still think a proper implementation of caching scheme is definitely an overkill. Instead this commit introduces limits to the maximum size (or minimum selectivity) of the intermediate results that can be cached.
75 lines
1.7 KiB
Go
75 lines
1.7 KiB
Go
package fzf
|
|
|
|
import (
|
|
"fmt"
|
|
"testing"
|
|
)
|
|
|
|
func TestChunkList(t *testing.T) {
|
|
cl := NewChunkList(func(s *string, i int) *Item {
|
|
return &Item{text: s, rank: Rank{0, 0, uint32(i * 2)}}
|
|
})
|
|
|
|
// Snapshot
|
|
snapshot, count := cl.Snapshot()
|
|
if len(snapshot) > 0 || count > 0 {
|
|
t.Error("Snapshot should be empty now")
|
|
}
|
|
|
|
// Add some data
|
|
cl.Push("hello")
|
|
cl.Push("world")
|
|
|
|
// Previously created snapshot should remain the same
|
|
if len(snapshot) > 0 {
|
|
t.Error("Snapshot should not have changed")
|
|
}
|
|
|
|
// But the new snapshot should contain the added items
|
|
snapshot, count = cl.Snapshot()
|
|
if len(snapshot) != 1 && count != 2 {
|
|
t.Error("Snapshot should not be empty now")
|
|
}
|
|
|
|
// Check the content of the ChunkList
|
|
chunk1 := snapshot[0]
|
|
if len(*chunk1) != 2 {
|
|
t.Error("Snapshot should contain only two items")
|
|
}
|
|
if *(*chunk1)[0].text != "hello" || (*chunk1)[0].rank.index != 0 ||
|
|
*(*chunk1)[1].text != "world" || (*chunk1)[1].rank.index != 2 {
|
|
t.Error("Invalid data")
|
|
}
|
|
if chunk1.IsFull() {
|
|
t.Error("Chunk should not have been marked full yet")
|
|
}
|
|
|
|
// Add more data
|
|
for i := 0; i < chunkSize*2; i++ {
|
|
cl.Push(fmt.Sprintf("item %d", i))
|
|
}
|
|
|
|
// Previous snapshot should remain the same
|
|
if len(snapshot) != 1 {
|
|
t.Error("Snapshot should stay the same")
|
|
}
|
|
|
|
// New snapshot
|
|
snapshot, count = cl.Snapshot()
|
|
if len(snapshot) != 3 || !snapshot[0].IsFull() ||
|
|
!snapshot[1].IsFull() || snapshot[2].IsFull() || count != chunkSize*2+2 {
|
|
t.Error("Expected two full chunks and one more chunk")
|
|
}
|
|
if len(*snapshot[2]) != 2 {
|
|
t.Error("Unexpected number of items")
|
|
}
|
|
|
|
cl.Push("hello")
|
|
cl.Push("world")
|
|
|
|
lastChunkCount := len(*snapshot[len(snapshot)-1])
|
|
if lastChunkCount != 2 {
|
|
t.Error("Unexpected number of items:", lastChunkCount)
|
|
}
|
|
}
|