diff --git a/src/chunklist_test.go b/src/chunklist_test.go index b244ece8..09e4aadd 100644 --- a/src/chunklist_test.go +++ b/src/chunklist_test.go @@ -7,7 +7,7 @@ import ( func TestChunkList(t *testing.T) { cl := NewChunkList(func(s *string, i int) *Item { - return &Item{text: s, index: i * 2} + return &Item{text: s, rank: Rank{0, 0, uint32(i * 2)}} }) // Snapshot @@ -36,8 +36,8 @@ func TestChunkList(t *testing.T) { if len(*chunk1) != 2 { t.Error("Snapshot should contain only two items") } - if *(*chunk1)[0].text != "hello" || (*chunk1)[0].index != 0 || - *(*chunk1)[1].text != "world" || (*chunk1)[1].index != 2 { + if *(*chunk1)[0].text != "hello" || (*chunk1)[0].rank.index != 0 || + *(*chunk1)[1].text != "world" || (*chunk1)[1].rank.index != 2 { t.Error("Invalid data") } if chunk1.IsFull() { diff --git a/src/core.go b/src/core.go index 5a81efa3..e5bdb129 100644 --- a/src/core.go +++ b/src/core.go @@ -39,14 +39,15 @@ func Run(options *Options) { var chunkList *ChunkList if len(opts.WithNth) == 0 { chunkList = NewChunkList(func(data *string, index int) *Item { - return &Item{text: data, index: index} + return &Item{text: data, rank: Rank{0, 0, uint32(index)}} }) } else { chunkList = NewChunkList(func(data *string, index int) *Item { - item := Item{text: data, index: index} - tokens := Tokenize(item.text, opts.Delimiter) - item.origText = item.text - item.text = Transform(tokens, opts.WithNth).whole + tokens := Tokenize(data, opts.Delimiter) + item := Item{ + text: Transform(tokens, opts.WithNth).whole, + origText: data, + rank: Rank{0, 0, uint32(index)}} return &item }) } diff --git a/src/item.go b/src/item.go index b70da93f..4c8f13d4 100644 --- a/src/item.go +++ b/src/item.go @@ -5,31 +5,32 @@ import ( "sort" ) -type Offset [2]int +type Offset [2]int32 type Item struct { text *string origText *string offsets []Offset - index int rank Rank transformed *Transformed } -type Rank [3]int - -var NilRank = Rank{-1, 0, 0} +type Rank struct { + matchlen uint16 + strlen uint16 + index uint32 +} func (i *Item) Rank() Rank { - if i.rank[0] > 0 { + if i.rank.matchlen > 0 || i.rank.strlen > 0 { return i.rank } sort.Sort(ByOrder(i.offsets)) matchlen := 0 prevEnd := 0 for _, offset := range i.offsets { - begin := offset[0] - end := offset[1] + begin := int(offset[0]) + end := int(offset[1]) if prevEnd > begin { begin = prevEnd } @@ -40,7 +41,7 @@ func (i *Item) Rank() Rank { matchlen += end - begin } } - i.rank = Rank{matchlen, len(*i.text), i.index} + i.rank = Rank{uint16(matchlen), uint16(len(*i.text)), i.rank.index} return i.rank } @@ -86,14 +87,22 @@ func (a ByRelevance) Less(i, j int) bool { } func compareRanks(irank Rank, jrank Rank) bool { - for idx := range irank { - if irank[idx] < jrank[idx] { - return true - } else if irank[idx] > jrank[idx] { - return false - } + if irank.matchlen < jrank.matchlen { + return true + } else if irank.matchlen > jrank.matchlen { + return false + } + + if irank.strlen < jrank.strlen { + return true + } else if irank.strlen > jrank.strlen { + return false + } + + if irank.index <= jrank.index { + return true } - return true + return false } func SortMerge(partialResults [][]*Item) []*Item { diff --git a/src/item_test.go b/src/item_test.go index 1e316291..23b8718c 100644 --- a/src/item_test.go +++ b/src/item_test.go @@ -23,8 +23,7 @@ func TestRankComparison(t *testing.T) { if compareRanks(Rank{3, 0, 5}, Rank{2, 0, 7}) || !compareRanks(Rank{3, 0, 5}, Rank{3, 0, 6}) || !compareRanks(Rank{1, 2, 3}, Rank{1, 3, 2}) || - !compareRanks(NilRank, Rank{0, 0, 0}) || - compareRanks(Rank{0, 0, 0}, NilRank) { + !compareRanks(Rank{0, 0, 0}, Rank{0, 0, 0}) { t.Error("Invalid order") } } @@ -32,13 +31,13 @@ func TestRankComparison(t *testing.T) { // Match length, string length, index func TestItemRank(t *testing.T) { strs := []string{"foo", "foobar", "bar", "baz"} - item1 := Item{text: &strs[0], index: 1, offsets: []Offset{}} + item1 := Item{text: &strs[0], rank: Rank{0, 0, 1}, offsets: []Offset{}} rank1 := item1.Rank() - if rank1[0] != 0 || rank1[1] != 3 || rank1[2] != 1 { + if rank1.matchlen != 0 || rank1.strlen != 3 || rank1.index != 1 { t.Error(item1.Rank()) } // Only differ in index - item2 := Item{text: &strs[0], index: 0, offsets: []Offset{}} + item2 := Item{text: &strs[0], rank: Rank{0, 0, 0}, offsets: []Offset{}} items := []*Item{&item1, &item2} sort.Sort(ByRelevance(items)) @@ -54,10 +53,10 @@ func TestItemRank(t *testing.T) { } // Sort by relevance - item3 := Item{text: &strs[1], index: 2, offsets: []Offset{Offset{1, 3}, Offset{5, 7}}} - item4 := Item{text: &strs[1], index: 2, offsets: []Offset{Offset{1, 2}, Offset{6, 7}}} - item5 := Item{text: &strs[2], index: 2, offsets: []Offset{Offset{1, 3}, Offset{5, 7}}} - item6 := Item{text: &strs[2], index: 2, offsets: []Offset{Offset{1, 2}, Offset{6, 7}}} + item3 := Item{text: &strs[1], rank: Rank{0, 0, 2}, offsets: []Offset{Offset{1, 3}, Offset{5, 7}}} + item4 := Item{text: &strs[1], rank: Rank{0, 0, 2}, offsets: []Offset{Offset{1, 2}, Offset{6, 7}}} + item5 := Item{text: &strs[2], rank: Rank{0, 0, 2}, offsets: []Offset{Offset{1, 3}, Offset{5, 7}}} + item6 := Item{text: &strs[2], rank: Rank{0, 0, 2}, offsets: []Offset{Offset{1, 2}, Offset{6, 7}}} items = []*Item{&item1, &item2, &item3, &item4, &item5, &item6} sort.Sort(ByRelevance(items)) if items[0] != &item2 || items[1] != &item1 || diff --git a/src/pattern.go b/src/pattern.go index 7c27f52f..7b294253 100644 --- a/src/pattern.go +++ b/src/pattern.go @@ -236,9 +236,8 @@ func (p *Pattern) fuzzyMatch(chunk *Chunk) []*Item { if sidx, eidx := p.iter(FuzzyMatch, input, p.text); sidx >= 0 { matches = append(matches, &Item{ text: item.text, - index: item.index, - offsets: []Offset{Offset{sidx, eidx}}, - rank: NilRank}) + offsets: []Offset{Offset{int32(sidx), int32(eidx)}}, + rank: Rank{0, 0, item.rank.index}}) } } return matches @@ -256,7 +255,7 @@ func (p *Pattern) extendedMatch(chunk *Chunk) []*Item { if term.inv { break Loop } - offsets = append(offsets, Offset{sidx, eidx}) + offsets = append(offsets, Offset{int32(sidx), int32(eidx)}) } else if term.inv { offsets = append(offsets, Offset{0, 0}) } @@ -264,9 +263,8 @@ func (p *Pattern) extendedMatch(chunk *Chunk) []*Item { if len(offsets) == len(p.terms) { matches = append(matches, &Item{ text: item.text, - index: item.index, offsets: offsets, - rank: NilRank}) + rank: Rank{0, 0, item.rank.index}}) } } return matches diff --git a/src/terminal.go b/src/terminal.go index a442d347..77a70f78 100644 --- a/src/terminal.go +++ b/src/terminal.go @@ -232,9 +232,9 @@ func trimRight(runes []rune, width int) ([]rune, int) { return runes, trimmed } -func trimLeft(runes []rune, width int) ([]rune, int) { +func trimLeft(runes []rune, width int) ([]rune, int32) { currentWidth := displayWidth(runes) - trimmed := 0 + var trimmed int32 = 0 for currentWidth > width && len(runes) > 0 { currentWidth -= runewidth.RuneWidth(runes[0]) @@ -245,7 +245,7 @@ func trimLeft(runes []rune, width int) ([]rune, int) { } func (*Terminal) printHighlighted(item *Item, bold bool, col1 int, col2 int) { - maxe := 0 + var maxe int32 = 0 for _, offset := range item.offsets { if offset[1] > maxe { maxe = offset[1] @@ -269,7 +269,7 @@ func (*Terminal) printHighlighted(item *Item, bold bool, col1 int, col2 int) { text = append(text[:maxe], []rune("..")...) } // ..ri.. - var diff int + var diff int32 text, diff = trimLeft(text, maxWidth-2) // Transform offsets @@ -278,7 +278,7 @@ func (*Terminal) printHighlighted(item *Item, bold bool, col1 int, col2 int) { b, e := offset[0], offset[1] b += 2 - diff e += 2 - diff - b = Max(b, 2) + b = Max32(b, 2) if b < e { offsets[idx] = Offset{b, e} } @@ -288,15 +288,15 @@ func (*Terminal) printHighlighted(item *Item, bold bool, col1 int, col2 int) { } sort.Sort(ByOrder(offsets)) - index := 0 + var index int32 = 0 for _, offset := range offsets { - b := Max(index, offset[0]) - e := Max(index, offset[1]) + b := Max32(index, offset[0]) + e := Max32(index, offset[1]) C.CPrint(col1, bold, string(text[index:b])) C.CPrint(col2, bold, string(text[b:e])) index = e } - if index < len(text) { + if index < int32(len(text)) { C.CPrint(col1, bold, string(text[index:])) } } diff --git a/src/util.go b/src/util.go index cc8d4f5d..de6f3654 100644 --- a/src/util.go +++ b/src/util.go @@ -12,6 +12,13 @@ func Max(first int, items ...int) int { return max } +func Max32(first int32, second int32) int32 { + if first > second { + return first + } + return second +} + func Min(first int, items ...int) int { min := first for _, item := range items {