summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJunegunn Choi <junegunn.c@gmail.com>2015-01-09 02:37:08 +0900
committerJunegunn Choi <junegunn.c@gmail.com>2015-01-09 10:42:12 +0900
commitaa05bf5206768965e575b6032543745c830e6eea (patch)
tree46689067f45992915ea6549266825556743b489a
parentd303c5b3ebc6d56af6d3a03c6b4cdb361a2b022c (diff)
Reduce memory footprint
-rw-r--r--src/chunklist_test.go6
-rw-r--r--src/core.go11
-rw-r--r--src/item.go41
-rw-r--r--src/item_test.go17
-rw-r--r--src/pattern.go10
-rw-r--r--src/terminal.go18
-rw-r--r--src/util.go7
7 files changed, 62 insertions, 48 deletions
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 {