Fix --no-sort jumpiness by merging results in index order

Fix #4717
This commit is contained in:
Junegunn Choi
2026-03-14 20:43:30 +09:00
parent b80059e21f
commit 7a811f0cb8
2 changed files with 19 additions and 11 deletions

View File

@@ -136,14 +136,7 @@ func (mg *Merger) Get(idx int) Result {
if mg.tac {
idx = mg.count - idx - 1
}
for _, list := range mg.lists {
numItems := len(list)
if idx < numItems {
return list[idx]
}
idx -= numItems
}
panic(fmt.Sprintf("Index out of bounds (unsorted, %d/%d)", idx, mg.count))
return mg.mergedGet(idx)
}
func (mg *Merger) ToMap() map[int32]Result {
@@ -171,7 +164,7 @@ func (mg *Merger) mergedGet(idx int) Result {
}
if cursor >= 0 {
rank := list[cursor]
if minIdx < 0 || compareRanks(rank, minRank, mg.tac) {
if minIdx < 0 || mg.sorted && compareRanks(rank, minRank, mg.tac) || !mg.sorted && rank.item.Index() < minRank.item.Index() {
minRank = rank
minIdx = listIdx
}

View File

@@ -54,10 +54,25 @@ func buildLists(partiallySorted bool) ([][]Result, []Result) {
}
func TestMergerUnsorted(t *testing.T) {
lists, items := buildLists(false)
lists, _ := buildLists(false)
// Sort each list by index to simulate real worker behavior
// (workers process chunks in ascending order via nextChunk.Add(1))
for _, list := range lists {
sort.Slice(list, func(i, j int) bool {
return list[i].item.Index() < list[j].item.Index()
})
}
items := []Result{}
for _, list := range lists {
items = append(items, list...)
}
sort.Slice(items, func(i, j int) bool {
return items[i].item.Index() < items[j].item.Index()
})
cnt := len(items)
// Not sorted: same order
// Not sorted: items in ascending index order
mg := NewMerger(nil, lists, false, false, revision{}, 0, 0)
assert(t, cnt == mg.Length(), "Invalid Length")
for i := range cnt {