Change Merger implementation on --no-sort
This commit is contained in:
parent
2d9b38b93e
commit
6e86fee588
@ -1,12 +1,15 @@
|
|||||||
package fzf
|
package fzf
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
var EmptyMerger *Merger = NewMerger([][]*Item{}, false)
|
var EmptyMerger *Merger = NewMerger([][]*Item{}, false)
|
||||||
|
|
||||||
type Merger struct {
|
type Merger struct {
|
||||||
lists [][]*Item
|
lists [][]*Item
|
||||||
merged []*Item
|
merged []*Item
|
||||||
cursors []int
|
cursors []int
|
||||||
done bool
|
sorted bool
|
||||||
|
count int
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewMerger(lists [][]*Item, sorted bool) *Merger {
|
func NewMerger(lists [][]*Item, sorted bool) *Merger {
|
||||||
@ -14,41 +17,37 @@ func NewMerger(lists [][]*Item, sorted bool) *Merger {
|
|||||||
lists: lists,
|
lists: lists,
|
||||||
merged: []*Item{},
|
merged: []*Item{},
|
||||||
cursors: make([]int, len(lists)),
|
cursors: make([]int, len(lists)),
|
||||||
done: false}
|
sorted: sorted,
|
||||||
if !sorted {
|
count: 0}
|
||||||
for _, list := range lists {
|
|
||||||
mg.merged = append(mg.merged, list...)
|
for _, list := range mg.lists {
|
||||||
}
|
mg.count += len(list)
|
||||||
mg.done = true
|
|
||||||
}
|
}
|
||||||
return &mg
|
return &mg
|
||||||
}
|
}
|
||||||
|
|
||||||
func (mg *Merger) Length() int {
|
func (mg *Merger) Length() int {
|
||||||
cnt := 0
|
return mg.count
|
||||||
for _, list := range mg.lists {
|
|
||||||
cnt += len(list)
|
|
||||||
}
|
|
||||||
return cnt
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (mg *Merger) Get(idx int) *Item {
|
func (mg *Merger) Get(idx int) *Item {
|
||||||
if mg.done {
|
if len(mg.lists) == 1 {
|
||||||
return mg.merged[idx]
|
|
||||||
} else if len(mg.lists) == 1 {
|
|
||||||
return mg.lists[0][idx]
|
return mg.lists[0][idx]
|
||||||
|
} else if !mg.sorted {
|
||||||
|
for _, list := range mg.lists {
|
||||||
|
numItems := len(list)
|
||||||
|
if idx < numItems {
|
||||||
|
return list[idx]
|
||||||
}
|
}
|
||||||
mg.buildUpto(idx)
|
idx -= numItems
|
||||||
return mg.merged[idx]
|
}
|
||||||
|
panic(fmt.Sprintf("Index out of bounds (unsorted, %d/%d)", idx, mg.count))
|
||||||
|
}
|
||||||
|
return mg.mergedGet(idx)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (mg *Merger) buildUpto(upto int) {
|
func (mg *Merger) mergedGet(idx int) *Item {
|
||||||
numBuilt := len(mg.merged)
|
for i := len(mg.merged); i <= idx; i++ {
|
||||||
if numBuilt > upto {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
for i := numBuilt; i <= upto; i++ {
|
|
||||||
minRank := Rank{0, 0, 0}
|
minRank := Rank{0, 0, 0}
|
||||||
minIdx := -1
|
minIdx := -1
|
||||||
for listIdx, list := range mg.lists {
|
for listIdx, list := range mg.lists {
|
||||||
@ -72,8 +71,8 @@ func (mg *Merger) buildUpto(upto int) {
|
|||||||
mg.merged = append(mg.merged, chosen[mg.cursors[minIdx]])
|
mg.merged = append(mg.merged, chosen[mg.cursors[minIdx]])
|
||||||
mg.cursors[minIdx] += 1
|
mg.cursors[minIdx] += 1
|
||||||
} else {
|
} else {
|
||||||
mg.done = true
|
panic(fmt.Sprintf("Index out of bounds (sorted, %d/%d)", i, mg.count))
|
||||||
return
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return mg.merged[idx]
|
||||||
}
|
}
|
||||||
|
@ -19,6 +19,9 @@ func randItem() *Item {
|
|||||||
|
|
||||||
func TestEmptyMerger(t *testing.T) {
|
func TestEmptyMerger(t *testing.T) {
|
||||||
assert(t, EmptyMerger.Length() == 0, "Not empty")
|
assert(t, EmptyMerger.Length() == 0, "Not empty")
|
||||||
|
assert(t, EmptyMerger.count == 0, "Invalid count")
|
||||||
|
assert(t, len(EmptyMerger.lists) == 0, "Invalid lists")
|
||||||
|
assert(t, len(EmptyMerger.merged) == 0, "Invalid merged list")
|
||||||
}
|
}
|
||||||
|
|
||||||
func buildLists(partiallySorted bool) ([][]*Item, []*Item) {
|
func buildLists(partiallySorted bool) ([][]*Item, []*Item) {
|
||||||
@ -72,7 +75,7 @@ func TestMergerSorted(t *testing.T) {
|
|||||||
|
|
||||||
// Inverse order
|
// Inverse order
|
||||||
mg2 := NewMerger(lists, true)
|
mg2 := NewMerger(lists, true)
|
||||||
for i := cnt - 1; i >= cnt; i-- {
|
for i := cnt - 1; i >= 0; i-- {
|
||||||
if items[i] != mg2.Get(i) {
|
if items[i] != mg2.Get(i) {
|
||||||
t.Error("Not sorted", items[i], mg2.Get(i))
|
t.Error("Not sorted", items[i], mg2.Get(i))
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user