You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
fzf/src/chunklist.go

90 lines
1.8 KiB
Go

10 years ago
package fzf
import "sync"
// Chunk is a list of Items whose size has the upper limit of chunkSize
type Chunk []Item
10 years ago
// ItemBuilder is a closure type that builds Item object from a pointer to a
10 years ago
// string and an integer
type ItemBuilder func([]byte, int) Item
10 years ago
10 years ago
// ChunkList is a list of Chunks
10 years ago
type ChunkList struct {
chunks []*Chunk
count int
mutex sync.Mutex
trans ItemBuilder
10 years ago
}
10 years ago
// NewChunkList returns a new ChunkList
func NewChunkList(trans ItemBuilder) *ChunkList {
10 years ago
return &ChunkList{
chunks: []*Chunk{},
count: 0,
mutex: sync.Mutex{},
trans: trans}
}
func (c *Chunk) push(trans ItemBuilder, data []byte, index int) bool {
item := trans(data, index)
if item.Nil() {
return false
}
*c = append(*c, item)
return true
10 years ago
}
10 years ago
// IsFull returns true if the Chunk is full
10 years ago
func (c *Chunk) IsFull() bool {
return len(*c) == chunkSize
10 years ago
}
func (cl *ChunkList) lastChunk() *Chunk {
return cl.chunks[len(cl.chunks)-1]
}
10 years ago
// CountItems returns the total number of Items
10 years ago
func CountItems(cs []*Chunk) int {
if len(cs) == 0 {
return 0
}
return chunkSize*(len(cs)-1) + len(*(cs[len(cs)-1]))
10 years ago
}
10 years ago
// Push adds the item to the list
func (cl *ChunkList) Push(data []byte) bool {
10 years ago
cl.mutex.Lock()
if len(cl.chunks) == 0 || cl.lastChunk().IsFull() {
newChunk := Chunk(make([]Item, 0, chunkSize))
10 years ago
cl.chunks = append(cl.chunks, &newChunk)
}
if cl.lastChunk().push(cl.trans, data, cl.count) {
cl.count++
cl.mutex.Unlock()
return true
}
cl.mutex.Unlock()
return false
10 years ago
}
10 years ago
// Snapshot returns immutable snapshot of the ChunkList
func (cl *ChunkList) Snapshot() ([]*Chunk, int) {
10 years ago
cl.mutex.Lock()
ret := make([]*Chunk, len(cl.chunks))
count := cl.count
10 years ago
copy(ret, cl.chunks)
// Duplicate the last chunk
if cnt := len(ret); cnt > 0 {
newChunk := *ret[cnt-1]
ret[cnt-1] = &newChunk
}
cl.mutex.Unlock()
return ret, count
}