fzf/src/cache.go

82 lines
1.6 KiB
Go
Raw Normal View History

2015-01-01 19:49:30 +00:00
package fzf
import "sync"
// queryCache associates strings to lists of items
type queryCache map[string][]*Result
2015-01-11 18:01:24 +00:00
// ChunkCache associates Chunk and query string to lists of items
2015-01-01 19:49:30 +00:00
type ChunkCache struct {
mutex sync.Mutex
cache map[*Chunk]*queryCache
2015-01-01 19:49:30 +00:00
}
2015-01-11 18:01:24 +00:00
// NewChunkCache returns a new ChunkCache
2015-01-01 19:49:30 +00:00
func NewChunkCache() ChunkCache {
return ChunkCache{sync.Mutex{}, make(map[*Chunk]*queryCache)}
2015-01-01 19:49:30 +00:00
}
2015-01-11 18:01:24 +00:00
// 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 {
2015-01-01 19:49:30 +00:00
return
}
cc.mutex.Lock()
defer cc.mutex.Unlock()
qc, ok := cc.cache[chunk]
if !ok {
cc.cache[chunk] = &queryCache{}
2015-01-01 19:49:30 +00:00
qc = cc.cache[chunk]
}
(*qc)[key] = list
}
2015-01-11 18:01:24 +00:00
// Find is called to lookup ChunkCache
func (cc *ChunkCache) Find(chunk *Chunk, key string) []*Result {
2015-01-01 19:49:30 +00:00
if len(key) == 0 || !chunk.IsFull() {
return nil
2015-01-01 19:49:30 +00:00
}
cc.mutex.Lock()
defer cc.mutex.Unlock()
qc, ok := cc.cache[chunk]
if ok {
list, ok := (*qc)[key]
if ok {
return list
2015-01-01 19:49:30 +00:00
}
}
return nil
}
func (cc *ChunkCache) Search(chunk *Chunk, key string) []*Result {
if len(key) == 0 || !chunk.IsFull() {
return nil
}
cc.mutex.Lock()
defer cc.mutex.Unlock()
qc, ok := cc.cache[chunk]
if !ok {
return nil
}
for idx := 1; idx < len(key); idx++ {
// [---------| ] | [ |---------]
// [--------| ] | [ |--------]
// [-------| ] | [ |-------]
prefix := key[:len(key)-idx]
suffix := key[idx:]
for _, substr := range [2]string{prefix, suffix} {
if cached, found := (*qc)[substr]; found {
return cached
}
}
}
return nil
2015-01-01 19:49:30 +00:00
}