package fzf
import “sync”
// Chunk is a list of Items whose size has the upper limit of chunkSize type Chunk struct {
items [chunkSize]Item count int
}
// ItemBuilder is a closure type that builds Item object from byte array type ItemBuilder func(*Item, []byte) bool
// ChunkList is a list of Chunks type ChunkList struct {
chunks []*Chunk mutex sync.Mutex trans ItemBuilder
}
// NewChunkList returns a new ChunkList func NewChunkList(trans ItemBuilder) *ChunkList {
return &ChunkList{ chunks: []*Chunk{}, mutex: sync.Mutex{}, trans: trans}
}
func (c *Chunk) push(trans ItemBuilder, data []byte) bool {
if trans(&c.items[c.count], data) { c.count++ return true } return false
}
// IsFull returns true if the Chunk is full func (c *Chunk) IsFull() bool {
return c.count == chunkSize
}
func (cl *ChunkList) lastChunk() *Chunk {
return cl.chunks[len(cl.chunks)-1]
}
// CountItems returns the total number of Items func CountItems(cs []*Chunk) int {
if len(cs) == 0 { return 0 } return chunkSize*(len(cs)-1) + cs[len(cs)-1].count
}
// Push adds the item to the list func (cl *ChunkList) Push(data []byte) bool {
cl.mutex.Lock() if len(cl.chunks) == 0 || cl.lastChunk().IsFull() { cl.chunks = append(cl.chunks, &Chunk{}) } ret := cl.lastChunk().push(cl.trans, data) cl.mutex.Unlock() return ret
}
// Clear clears the data func (cl *ChunkList) Clear() {
cl.mutex.Lock() cl.chunks = nil cl.mutex.Unlock()
}
// Snapshot returns immutable snapshot of the ChunkList func (cl *ChunkList) Snapshot() ([]*Chunk, int) {
cl.mutex.Lock() ret := make([]*Chunk, len(cl.chunks)) 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, CountItems(ret)
}