mirror of
https://github.com/Llewellynvdm/fzf.git
synced 2024-11-11 00:00:55 +00:00
Reduce memory footprint
This commit is contained in:
parent
d303c5b3eb
commit
aa05bf5206
@ -7,7 +7,7 @@ import (
|
|||||||
|
|
||||||
func TestChunkList(t *testing.T) {
|
func TestChunkList(t *testing.T) {
|
||||||
cl := NewChunkList(func(s *string, i int) *Item {
|
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
|
// Snapshot
|
||||||
@ -36,8 +36,8 @@ func TestChunkList(t *testing.T) {
|
|||||||
if len(*chunk1) != 2 {
|
if len(*chunk1) != 2 {
|
||||||
t.Error("Snapshot should contain only two items")
|
t.Error("Snapshot should contain only two items")
|
||||||
}
|
}
|
||||||
if *(*chunk1)[0].text != "hello" || (*chunk1)[0].index != 0 ||
|
if *(*chunk1)[0].text != "hello" || (*chunk1)[0].rank.index != 0 ||
|
||||||
*(*chunk1)[1].text != "world" || (*chunk1)[1].index != 2 {
|
*(*chunk1)[1].text != "world" || (*chunk1)[1].rank.index != 2 {
|
||||||
t.Error("Invalid data")
|
t.Error("Invalid data")
|
||||||
}
|
}
|
||||||
if chunk1.IsFull() {
|
if chunk1.IsFull() {
|
||||||
|
11
src/core.go
11
src/core.go
@ -39,14 +39,15 @@ func Run(options *Options) {
|
|||||||
var chunkList *ChunkList
|
var chunkList *ChunkList
|
||||||
if len(opts.WithNth) == 0 {
|
if len(opts.WithNth) == 0 {
|
||||||
chunkList = NewChunkList(func(data *string, index int) *Item {
|
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 {
|
} else {
|
||||||
chunkList = NewChunkList(func(data *string, index int) *Item {
|
chunkList = NewChunkList(func(data *string, index int) *Item {
|
||||||
item := Item{text: data, index: index}
|
tokens := Tokenize(data, opts.Delimiter)
|
||||||
tokens := Tokenize(item.text, opts.Delimiter)
|
item := Item{
|
||||||
item.origText = item.text
|
text: Transform(tokens, opts.WithNth).whole,
|
||||||
item.text = Transform(tokens, opts.WithNth).whole
|
origText: data,
|
||||||
|
rank: Rank{0, 0, uint32(index)}}
|
||||||
return &item
|
return &item
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
35
src/item.go
35
src/item.go
@ -5,31 +5,32 @@ import (
|
|||||||
"sort"
|
"sort"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Offset [2]int
|
type Offset [2]int32
|
||||||
|
|
||||||
type Item struct {
|
type Item struct {
|
||||||
text *string
|
text *string
|
||||||
origText *string
|
origText *string
|
||||||
offsets []Offset
|
offsets []Offset
|
||||||
index int
|
|
||||||
rank Rank
|
rank Rank
|
||||||
transformed *Transformed
|
transformed *Transformed
|
||||||
}
|
}
|
||||||
|
|
||||||
type Rank [3]int
|
type Rank struct {
|
||||||
|
matchlen uint16
|
||||||
var NilRank = Rank{-1, 0, 0}
|
strlen uint16
|
||||||
|
index uint32
|
||||||
|
}
|
||||||
|
|
||||||
func (i *Item) Rank() Rank {
|
func (i *Item) Rank() Rank {
|
||||||
if i.rank[0] > 0 {
|
if i.rank.matchlen > 0 || i.rank.strlen > 0 {
|
||||||
return i.rank
|
return i.rank
|
||||||
}
|
}
|
||||||
sort.Sort(ByOrder(i.offsets))
|
sort.Sort(ByOrder(i.offsets))
|
||||||
matchlen := 0
|
matchlen := 0
|
||||||
prevEnd := 0
|
prevEnd := 0
|
||||||
for _, offset := range i.offsets {
|
for _, offset := range i.offsets {
|
||||||
begin := offset[0]
|
begin := int(offset[0])
|
||||||
end := offset[1]
|
end := int(offset[1])
|
||||||
if prevEnd > begin {
|
if prevEnd > begin {
|
||||||
begin = prevEnd
|
begin = prevEnd
|
||||||
}
|
}
|
||||||
@ -40,7 +41,7 @@ func (i *Item) Rank() Rank {
|
|||||||
matchlen += end - begin
|
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
|
return i.rank
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -86,14 +87,22 @@ func (a ByRelevance) Less(i, j int) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func compareRanks(irank Rank, jrank Rank) bool {
|
func compareRanks(irank Rank, jrank Rank) bool {
|
||||||
for idx := range irank {
|
if irank.matchlen < jrank.matchlen {
|
||||||
if irank[idx] < jrank[idx] {
|
|
||||||
return true
|
return true
|
||||||
} else if irank[idx] > jrank[idx] {
|
} else if irank.matchlen > jrank.matchlen {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
if irank.strlen < jrank.strlen {
|
||||||
return true
|
return true
|
||||||
|
} else if irank.strlen > jrank.strlen {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
if irank.index <= jrank.index {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func SortMerge(partialResults [][]*Item) []*Item {
|
func SortMerge(partialResults [][]*Item) []*Item {
|
||||||
|
@ -23,8 +23,7 @@ func TestRankComparison(t *testing.T) {
|
|||||||
if compareRanks(Rank{3, 0, 5}, Rank{2, 0, 7}) ||
|
if compareRanks(Rank{3, 0, 5}, Rank{2, 0, 7}) ||
|
||||||
!compareRanks(Rank{3, 0, 5}, Rank{3, 0, 6}) ||
|
!compareRanks(Rank{3, 0, 5}, Rank{3, 0, 6}) ||
|
||||||
!compareRanks(Rank{1, 2, 3}, Rank{1, 3, 2}) ||
|
!compareRanks(Rank{1, 2, 3}, Rank{1, 3, 2}) ||
|
||||||
!compareRanks(NilRank, Rank{0, 0, 0}) ||
|
!compareRanks(Rank{0, 0, 0}, Rank{0, 0, 0}) {
|
||||||
compareRanks(Rank{0, 0, 0}, NilRank) {
|
|
||||||
t.Error("Invalid order")
|
t.Error("Invalid order")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -32,13 +31,13 @@ func TestRankComparison(t *testing.T) {
|
|||||||
// Match length, string length, index
|
// Match length, string length, index
|
||||||
func TestItemRank(t *testing.T) {
|
func TestItemRank(t *testing.T) {
|
||||||
strs := []string{"foo", "foobar", "bar", "baz"}
|
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()
|
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())
|
t.Error(item1.Rank())
|
||||||
}
|
}
|
||||||
// Only differ in index
|
// 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}
|
items := []*Item{&item1, &item2}
|
||||||
sort.Sort(ByRelevance(items))
|
sort.Sort(ByRelevance(items))
|
||||||
@ -54,10 +53,10 @@ func TestItemRank(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Sort by relevance
|
// Sort by relevance
|
||||||
item3 := Item{text: &strs[1], index: 2, offsets: []Offset{Offset{1, 3}, Offset{5, 7}}}
|
item3 := Item{text: &strs[1], rank: Rank{0, 0, 2}, offsets: []Offset{Offset{1, 3}, Offset{5, 7}}}
|
||||||
item4 := Item{text: &strs[1], index: 2, offsets: []Offset{Offset{1, 2}, Offset{6, 7}}}
|
item4 := Item{text: &strs[1], rank: Rank{0, 0, 2}, offsets: []Offset{Offset{1, 2}, Offset{6, 7}}}
|
||||||
item5 := Item{text: &strs[2], index: 2, offsets: []Offset{Offset{1, 3}, Offset{5, 7}}}
|
item5 := Item{text: &strs[2], rank: Rank{0, 0, 2}, offsets: []Offset{Offset{1, 3}, Offset{5, 7}}}
|
||||||
item6 := Item{text: &strs[2], index: 2, offsets: []Offset{Offset{1, 2}, Offset{6, 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}
|
items = []*Item{&item1, &item2, &item3, &item4, &item5, &item6}
|
||||||
sort.Sort(ByRelevance(items))
|
sort.Sort(ByRelevance(items))
|
||||||
if items[0] != &item2 || items[1] != &item1 ||
|
if items[0] != &item2 || items[1] != &item1 ||
|
||||||
|
@ -236,9 +236,8 @@ func (p *Pattern) fuzzyMatch(chunk *Chunk) []*Item {
|
|||||||
if sidx, eidx := p.iter(FuzzyMatch, input, p.text); sidx >= 0 {
|
if sidx, eidx := p.iter(FuzzyMatch, input, p.text); sidx >= 0 {
|
||||||
matches = append(matches, &Item{
|
matches = append(matches, &Item{
|
||||||
text: item.text,
|
text: item.text,
|
||||||
index: item.index,
|
offsets: []Offset{Offset{int32(sidx), int32(eidx)}},
|
||||||
offsets: []Offset{Offset{sidx, eidx}},
|
rank: Rank{0, 0, item.rank.index}})
|
||||||
rank: NilRank})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return matches
|
return matches
|
||||||
@ -256,7 +255,7 @@ func (p *Pattern) extendedMatch(chunk *Chunk) []*Item {
|
|||||||
if term.inv {
|
if term.inv {
|
||||||
break Loop
|
break Loop
|
||||||
}
|
}
|
||||||
offsets = append(offsets, Offset{sidx, eidx})
|
offsets = append(offsets, Offset{int32(sidx), int32(eidx)})
|
||||||
} else if term.inv {
|
} else if term.inv {
|
||||||
offsets = append(offsets, Offset{0, 0})
|
offsets = append(offsets, Offset{0, 0})
|
||||||
}
|
}
|
||||||
@ -264,9 +263,8 @@ func (p *Pattern) extendedMatch(chunk *Chunk) []*Item {
|
|||||||
if len(offsets) == len(p.terms) {
|
if len(offsets) == len(p.terms) {
|
||||||
matches = append(matches, &Item{
|
matches = append(matches, &Item{
|
||||||
text: item.text,
|
text: item.text,
|
||||||
index: item.index,
|
|
||||||
offsets: offsets,
|
offsets: offsets,
|
||||||
rank: NilRank})
|
rank: Rank{0, 0, item.rank.index}})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return matches
|
return matches
|
||||||
|
@ -232,9 +232,9 @@ func trimRight(runes []rune, width int) ([]rune, int) {
|
|||||||
return runes, trimmed
|
return runes, trimmed
|
||||||
}
|
}
|
||||||
|
|
||||||
func trimLeft(runes []rune, width int) ([]rune, int) {
|
func trimLeft(runes []rune, width int) ([]rune, int32) {
|
||||||
currentWidth := displayWidth(runes)
|
currentWidth := displayWidth(runes)
|
||||||
trimmed := 0
|
var trimmed int32 = 0
|
||||||
|
|
||||||
for currentWidth > width && len(runes) > 0 {
|
for currentWidth > width && len(runes) > 0 {
|
||||||
currentWidth -= runewidth.RuneWidth(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) {
|
func (*Terminal) printHighlighted(item *Item, bold bool, col1 int, col2 int) {
|
||||||
maxe := 0
|
var maxe int32 = 0
|
||||||
for _, offset := range item.offsets {
|
for _, offset := range item.offsets {
|
||||||
if offset[1] > maxe {
|
if offset[1] > maxe {
|
||||||
maxe = offset[1]
|
maxe = offset[1]
|
||||||
@ -269,7 +269,7 @@ func (*Terminal) printHighlighted(item *Item, bold bool, col1 int, col2 int) {
|
|||||||
text = append(text[:maxe], []rune("..")...)
|
text = append(text[:maxe], []rune("..")...)
|
||||||
}
|
}
|
||||||
// ..ri..
|
// ..ri..
|
||||||
var diff int
|
var diff int32
|
||||||
text, diff = trimLeft(text, maxWidth-2)
|
text, diff = trimLeft(text, maxWidth-2)
|
||||||
|
|
||||||
// Transform offsets
|
// Transform offsets
|
||||||
@ -278,7 +278,7 @@ func (*Terminal) printHighlighted(item *Item, bold bool, col1 int, col2 int) {
|
|||||||
b, e := offset[0], offset[1]
|
b, e := offset[0], offset[1]
|
||||||
b += 2 - diff
|
b += 2 - diff
|
||||||
e += 2 - diff
|
e += 2 - diff
|
||||||
b = Max(b, 2)
|
b = Max32(b, 2)
|
||||||
if b < e {
|
if b < e {
|
||||||
offsets[idx] = Offset{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))
|
sort.Sort(ByOrder(offsets))
|
||||||
index := 0
|
var index int32 = 0
|
||||||
for _, offset := range offsets {
|
for _, offset := range offsets {
|
||||||
b := Max(index, offset[0])
|
b := Max32(index, offset[0])
|
||||||
e := Max(index, offset[1])
|
e := Max32(index, offset[1])
|
||||||
C.CPrint(col1, bold, string(text[index:b]))
|
C.CPrint(col1, bold, string(text[index:b]))
|
||||||
C.CPrint(col2, bold, string(text[b:e]))
|
C.CPrint(col2, bold, string(text[b:e]))
|
||||||
index = e
|
index = e
|
||||||
}
|
}
|
||||||
if index < len(text) {
|
if index < int32(len(text)) {
|
||||||
C.CPrint(col1, bold, string(text[index:]))
|
C.CPrint(col1, bold, string(text[index:]))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,6 +12,13 @@ func Max(first int, items ...int) int {
|
|||||||
return max
|
return max
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func Max32(first int32, second int32) int32 {
|
||||||
|
if first > second {
|
||||||
|
return first
|
||||||
|
}
|
||||||
|
return second
|
||||||
|
}
|
||||||
|
|
||||||
func Min(first int, items ...int) int {
|
func Min(first int, items ...int) int {
|
||||||
min := first
|
min := first
|
||||||
for _, item := range items {
|
for _, item := range items {
|
||||||
|
Loading…
Reference in New Issue
Block a user