Remove pointer indirection by changing Chunk definition

This commit is contained in:
Junegunn Choi
2017-07-15 12:28:29 +09:00
parent 7b5ccc45bc
commit d4f3d5a164
7 changed files with 29 additions and 23 deletions

View File

@@ -2,12 +2,12 @@ package fzf
import "sync" import "sync"
// Chunk is a list of Item pointers whose size has the upper limit of chunkSize // Chunk is a list of Items whose size has the upper limit of chunkSize
type Chunk []*Item // >>> []Item type Chunk []Item
// ItemBuilder is a closure type that builds Item object from a pointer to a // ItemBuilder is a closure type that builds Item object from a pointer to a
// string and an integer // string and an integer
type ItemBuilder func([]byte, int) *Item type ItemBuilder func([]byte, int) Item
// ChunkList is a list of Chunks // ChunkList is a list of Chunks
type ChunkList struct { type ChunkList struct {
@@ -28,11 +28,11 @@ func NewChunkList(trans ItemBuilder) *ChunkList {
func (c *Chunk) push(trans ItemBuilder, data []byte, index int) bool { func (c *Chunk) push(trans ItemBuilder, data []byte, index int) bool {
item := trans(data, index) item := trans(data, index)
if item != nil { if item.Nil() {
*c = append(*c, item) return false
return true
} }
return false *c = append(*c, item)
return true
} }
// IsFull returns true if the Chunk is full // IsFull returns true if the Chunk is full
@@ -58,7 +58,7 @@ func (cl *ChunkList) Push(data []byte) bool {
defer cl.mutex.Unlock() defer cl.mutex.Unlock()
if len(cl.chunks) == 0 || cl.lastChunk().IsFull() { if len(cl.chunks) == 0 || cl.lastChunk().IsFull() {
newChunk := Chunk(make([]*Item, 0, chunkSize)) newChunk := Chunk(make([]Item, 0, chunkSize))
cl.chunks = append(cl.chunks, &newChunk) cl.chunks = append(cl.chunks, &newChunk)
} }

View File

@@ -11,8 +11,8 @@ func TestChunkList(t *testing.T) {
// FIXME global // FIXME global
sortCriteria = []criterion{byScore, byLength} sortCriteria = []criterion{byScore, byLength}
cl := NewChunkList(func(s []byte, i int) *Item { cl := NewChunkList(func(s []byte, i int) Item {
return &Item{text: util.ToChars(s), index: int32(i * 2)} return Item{text: util.ToChars(s), index: int32(i * 2)}
}) })
// Snapshot // Snapshot

View File

@@ -91,27 +91,27 @@ func Run(opts *Options, revision string) {
var chunkList *ChunkList var chunkList *ChunkList
header := make([]string, 0, opts.HeaderLines) header := make([]string, 0, opts.HeaderLines)
if len(opts.WithNth) == 0 { if len(opts.WithNth) == 0 {
chunkList = NewChunkList(func(data []byte, index int) *Item { chunkList = NewChunkList(func(data []byte, index int) Item {
if len(header) < opts.HeaderLines { if len(header) < opts.HeaderLines {
header = append(header, string(data)) header = append(header, string(data))
eventBox.Set(EvtHeader, header) eventBox.Set(EvtHeader, header)
return nil return nilItem
} }
chars, colors := ansiProcessor(data) chars, colors := ansiProcessor(data)
return &Item{ return Item{
index: int32(index), index: int32(index),
trimLength: -1, trimLength: -1,
text: chars, text: chars,
colors: colors} colors: colors}
}) })
} else { } else {
chunkList = NewChunkList(func(data []byte, index int) *Item { chunkList = NewChunkList(func(data []byte, index int) Item {
tokens := Tokenize(util.ToChars(data), opts.Delimiter) tokens := Tokenize(util.ToChars(data), opts.Delimiter)
trans := Transform(tokens, opts.WithNth) trans := Transform(tokens, opts.WithNth)
if len(header) < opts.HeaderLines { if len(header) < opts.HeaderLines {
header = append(header, string(joinTokens(trans))) header = append(header, string(joinTokens(trans)))
eventBox.Set(EvtHeader, header) eventBox.Set(EvtHeader, header)
return nil return nilItem
} }
textRunes := joinTokens(trans) textRunes := joinTokens(trans)
item := Item{ item := Item{
@@ -123,7 +123,7 @@ func Run(opts *Options, revision string) {
trimmed, colors := ansiProcessorRunes(textRunes) trimmed, colors := ansiProcessorRunes(textRunes)
item.text = trimmed item.text = trimmed
item.colors = colors item.colors = colors
return &item return item
}) })
} }
@@ -168,8 +168,8 @@ func Run(opts *Options, revision string) {
reader := Reader{ reader := Reader{
func(runes []byte) bool { func(runes []byte) bool {
item := chunkList.trans(runes, 0) item := chunkList.trans(runes, 0)
if item != nil { if !item.Nil() {
if result, _, _ := pattern.MatchItem(item, false, slab); result != nil { if result, _, _ := pattern.MatchItem(&item, false, slab); result != nil {
opts.Printer(item.text.ToString()) opts.Printer(item.text.ToString())
found = true found = true
} }

View File

@@ -19,6 +19,12 @@ func (item *Item) Index() int32 {
return item.index return item.index
} }
var nilItem = Item{index: -1}
func (item *Item) Nil() bool {
return item.index < 0
}
func (item *Item) TrimLength() int32 { func (item *Item) TrimLength() int32 {
if item.trimLength >= 0 { if item.trimLength >= 0 {
return item.trimLength return item.trimLength

View File

@@ -65,7 +65,7 @@ func (mg *Merger) Get(idx int) *Result {
idx = mg.count - idx - 1 idx = mg.count - idx - 1
} }
chunk := (*mg.chunks)[idx/chunkSize] chunk := (*mg.chunks)[idx/chunkSize]
return &Result{item: (*chunk)[idx%chunkSize]} return &Result{item: &(*chunk)[idx%chunkSize]}
} }
if mg.sorted { if mg.sorted {

View File

@@ -281,8 +281,8 @@ func (p *Pattern) matchChunk(chunk *Chunk, space []*Result, slab *util.Slab) []*
matches := []*Result{} matches := []*Result{}
if space == nil { if space == nil {
for _, item := range *chunk { for idx := range *chunk {
if match, _, _ := p.MatchItem(item, false, slab); match != nil { if match, _, _ := p.MatchItem(&(*chunk)[idx], false, slab); match != nil {
matches = append(matches, match) matches = append(matches, match)
} }
} }

View File

@@ -139,7 +139,7 @@ func TestOrigTextAndTransformed(t *testing.T) {
origBytes := []byte("junegunn.choi") origBytes := []byte("junegunn.choi")
for _, extended := range []bool{false, true} { for _, extended := range []bool{false, true} {
chunk := Chunk{ chunk := Chunk{
&Item{ Item{
text: util.RunesToChars([]rune("junegunn")), text: util.RunesToChars([]rune("junegunn")),
origText: &origBytes, origText: &origBytes,
transformed: trans}, transformed: trans},
@@ -152,7 +152,7 @@ func TestOrigTextAndTransformed(t *testing.T) {
t.Error("Invalid match result", matches) t.Error("Invalid match result", matches)
} }
match, offsets, pos := pattern.MatchItem(chunk[0], true, slab) match, offsets, pos := pattern.MatchItem(&chunk[0], true, slab)
if !(match.item.text.ToString() == "junegunn" && if !(match.item.text.ToString() == "junegunn" &&
string(*match.item.origText) == "junegunn.choi" && string(*match.item.origText) == "junegunn.choi" &&
offsets[0][0] == 0 && offsets[0][1] == 5 && offsets[0][0] == 0 && offsets[0][1] == 5 &&