summaryrefslogtreecommitdiffstats
path: root/src/chunklist.go
blob: b1f9638da77d094494646e1ee32c6ee907b17d0e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
package fzf

import "sync"

const CHUNK_SIZE int = 100

type Chunk []*Item // >>> []Item

type Transformer func(*string, int) *Item

type ChunkList struct {
	chunks []*Chunk
	count  int
	mutex  sync.Mutex
	trans  Transformer
}

func NewChunkList(trans Transformer) *ChunkList {
	return &ChunkList{
		chunks: []*Chunk{},
		count:  0,
		mutex:  sync.Mutex{},
		trans:  trans}
}

func (c *Chunk) push(trans Transformer, data *string, index int) {
	*c = append(*c, trans(data, index))
}

func (c *Chunk) IsFull() bool {
	return len(*c) == CHUNK_SIZE
}

func (cl *ChunkList) lastChunk() *Chunk {
	return cl.chunks[len(cl.chunks)-1]
}

func CountItems(cs []*Chunk) int {
	if len(cs) == 0 {
		return 0
	}
	return CHUNK_SIZE*(len(cs)-1) + len(*(cs[len(cs)-1]))
}

func (cl *ChunkList) Count() int {
	return cl.count
}

func (cl *ChunkList) Chunks() []*Chunk {
	return cl.chunks
}

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, CHUNK_SIZE))
		cl.chunks = append(cl.chunks, &newChunk)
	}

	cl.lastChunk().push(cl.trans, &data, cl.count)
	cl.count += 1
}

func (cl *ChunkList) Snapshot() []*Chunk {
	cl.mutex.Lock()
	defer cl.mutex.Unlock()

	ret := make([]*Chunk, len(cl.chunks))
	copy(ret, cl.chunks)
	return ret
}