fzf/src/chunklist.go

86 lines
1.8 KiB
Go
Raw Normal View History

2015-01-01 19:49:30 +00:00
package fzf
import "sync"
// Chunk is a list of Item pointers whose size has the upper limit of chunkSize
2015-01-01 19:49:30 +00:00
type Chunk []*Item // >>> []Item
2015-01-12 03:56:17 +00:00
// ItemBuilder is a closure type that builds Item object from a pointer to a
2015-01-11 18:01:24 +00:00
// string and an integer
2015-01-12 03:56:17 +00:00
type ItemBuilder func(*string, int) *Item
2015-01-01 19:49:30 +00:00
2015-01-11 18:01:24 +00:00
// ChunkList is a list of Chunks
2015-01-01 19:49:30 +00:00
type ChunkList struct {
chunks []*Chunk
count int
mutex sync.Mutex
2015-01-12 03:56:17 +00:00
trans ItemBuilder
2015-01-01 19:49:30 +00:00
}
2015-01-11 18:01:24 +00:00
// NewChunkList returns a new ChunkList
2015-01-12 03:56:17 +00:00
func NewChunkList(trans ItemBuilder) *ChunkList {
2015-01-01 19:49:30 +00:00
return &ChunkList{
chunks: []*Chunk{},
count: 0,
mutex: sync.Mutex{},
trans: trans}
}
2015-01-12 03:56:17 +00:00
func (c *Chunk) push(trans ItemBuilder, data *string, index int) {
2015-01-01 19:49:30 +00:00
*c = append(*c, trans(data, index))
}
2015-01-11 18:01:24 +00:00
// IsFull returns true if the Chunk is full
2015-01-01 19:49:30 +00:00
func (c *Chunk) IsFull() bool {
return len(*c) == chunkSize
2015-01-01 19:49:30 +00:00
}
func (cl *ChunkList) lastChunk() *Chunk {
return cl.chunks[len(cl.chunks)-1]
}
2015-01-11 18:01:24 +00:00
// CountItems returns the total number of Items
2015-01-01 19:49:30 +00:00
func CountItems(cs []*Chunk) int {
if len(cs) == 0 {
return 0
}
return chunkSize*(len(cs)-1) + len(*(cs[len(cs)-1]))
2015-01-01 19:49:30 +00:00
}
2015-01-11 18:01:24 +00:00
// Push adds the item to the list
2015-01-01 19:49:30 +00:00
func (cl *ChunkList) Push(data string) {
cl.mutex.Lock()
defer cl.mutex.Unlock()
if len(cl.chunks) == 0 || cl.lastChunk().IsFull() {
newChunk := Chunk(make([]*Item, 0, chunkSize))
2015-01-01 19:49:30 +00:00
cl.chunks = append(cl.chunks, &newChunk)
}
cl.lastChunk().push(cl.trans, &data, cl.count)
2015-01-11 18:01:24 +00:00
cl.count++
2015-01-01 19:49:30 +00:00
}
2015-01-11 18:01:24 +00:00
// Snapshot returns immutable snapshot of the ChunkList
func (cl *ChunkList) Snapshot() ([]*Chunk, int) {
2015-01-01 19:49:30 +00:00
cl.mutex.Lock()
defer cl.mutex.Unlock()
ret := make([]*Chunk, len(cl.chunks))
copy(ret, cl.chunks)
// Duplicate the last chunk
if cnt := len(ret); cnt > 0 {
ret[cnt-1] = ret[cnt-1].dupe()
}
return ret, cl.count
}
func (c *Chunk) dupe() *Chunk {
newChunk := make(Chunk, len(*c))
for idx, ptr := range *c {
newChunk[idx] = ptr
}
return &newChunk
2015-01-01 19:49:30 +00:00
}