mirror of
https://github.com/stablyai/orca.git
synced 2026-09-22 00:02:31 +00:00
perf: index selected ancestor coverage during sidebar drag (#19443)
* perf: index selected ancestor coverage during sidebar drag * test(sidebar): pin nested and sibling lineage expansion invariants --------- Co-authored-by: m4air <m4air@m4airs-MacBook-Air.local> Co-authored-by: Neil <4138956+nwparker@users.noreply.github.com>
This commit is contained in:
@@ -0,0 +1,88 @@
|
||||
import { describe, expect, it, vi } from 'vitest'
|
||||
import {
|
||||
expandDraggedWorktreeIdsForVisibleLineage,
|
||||
type WorktreeDragLineageRow
|
||||
} from './worktree-manual-order'
|
||||
|
||||
// Preserve the original traversal as an independent ordering oracle.
|
||||
function referenceExpansion(
|
||||
rows: readonly WorktreeDragLineageRow[],
|
||||
draggedIds: readonly string[]
|
||||
) {
|
||||
const dragged = new Set(draggedIds)
|
||||
const expanded = new Set(draggedIds)
|
||||
const rowIds = new Set(rows.map((row) => row.worktreeId))
|
||||
for (let index = 0; index < rows.length; index++) {
|
||||
const row = rows[index]
|
||||
if (!dragged.has(row.worktreeId)) {
|
||||
continue
|
||||
}
|
||||
for (let cursor = index + 1; cursor < rows.length; cursor++) {
|
||||
const child = rows[cursor]
|
||||
if (child.depth <= row.depth) {
|
||||
break
|
||||
}
|
||||
expanded.add(child.worktreeId)
|
||||
}
|
||||
}
|
||||
const result = rows.filter((row) => expanded.has(row.worktreeId)).map((row) => row.worktreeId)
|
||||
for (const id of draggedIds) {
|
||||
if (!rowIds.has(id) && !result.includes(id)) {
|
||||
result.push(id)
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
describe('visible lineage expansion scaling', () => {
|
||||
it('reads each depth once even when every ancestor is selected', () => {
|
||||
let depthReads = 0
|
||||
const rows = Array.from({ length: 2_000 }, (_, index) => ({
|
||||
worktreeId: `wt-${index}`,
|
||||
get depth() {
|
||||
depthReads++
|
||||
return index
|
||||
}
|
||||
}))
|
||||
const selected = rows.map((row) => row.worktreeId)
|
||||
expect(referenceExpansion(rows, selected)).toEqual(selected)
|
||||
expect(depthReads).toBe(rows.length * (rows.length - 1))
|
||||
depthReads = 0
|
||||
expect(expandDraggedWorktreeIdsForVisibleLineage(rows, selected)).toEqual(selected)
|
||||
expect(depthReads).toBe(rows.length)
|
||||
})
|
||||
|
||||
it('deduplicates many absent selected rows without searching the growing result', () => {
|
||||
const selected = Array.from({ length: 5_000 }, (_, index) => `missing-${index}`)
|
||||
const includes = vi.spyOn(Array.prototype, 'includes')
|
||||
let calls: number
|
||||
let result: string[]
|
||||
try {
|
||||
result = expandDraggedWorktreeIdsForVisibleLineage([], [...selected, ...selected])
|
||||
calls = includes.mock.calls.length
|
||||
} finally {
|
||||
includes.mockRestore()
|
||||
}
|
||||
expect(result).toEqual(selected)
|
||||
expect(calls).toBe(0)
|
||||
})
|
||||
|
||||
it('matches the previous algorithm across duplicate rows, missing IDs and depth boundaries', () => {
|
||||
let seed = 12345
|
||||
function random(limit: number): number {
|
||||
seed = (Math.imul(seed, 1664525) + 1013904223) >>> 0
|
||||
return seed % limit
|
||||
}
|
||||
const depths = [-1, 0, 1, 2, 3, 20, Infinity, -Infinity, Number.NaN]
|
||||
for (let sample = 0; sample < 500; sample++) {
|
||||
const rows = Array.from({ length: random(40) }, () => ({
|
||||
worktreeId: `wt-${random(20)}`,
|
||||
depth: depths[random(depths.length)]
|
||||
}))
|
||||
const selected = Array.from({ length: random(20) }, () => `wt-${random(25)}`)
|
||||
expect(expandDraggedWorktreeIdsForVisibleLineage(rows, selected)).toEqual(
|
||||
referenceExpansion(rows, selected)
|
||||
)
|
||||
}
|
||||
})
|
||||
})
|
||||
@@ -120,6 +120,44 @@ describe('expandDraggedWorktreeIdsForVisibleLineage', () => {
|
||||
)
|
||||
).toEqual(['parent', 'child', 'z'])
|
||||
})
|
||||
|
||||
// Single-pass coverage must not end early when a descendant is also selected.
|
||||
it('keeps ancestor coverage when a nested descendant is selected too', () => {
|
||||
expect(
|
||||
expandDraggedWorktreeIdsForVisibleLineage(
|
||||
[
|
||||
{ worktreeId: 'parent', depth: 0 },
|
||||
{ worktreeId: 'child', depth: 2 },
|
||||
{ worktreeId: 'uncleish', depth: 1 },
|
||||
{ worktreeId: 'sibling', depth: 0 }
|
||||
],
|
||||
['parent', 'child']
|
||||
)
|
||||
).toEqual(['parent', 'child', 'uncleish'])
|
||||
})
|
||||
|
||||
it('restarts coverage for a later selected sibling after the previous run ends', () => {
|
||||
expect(
|
||||
expandDraggedWorktreeIdsForVisibleLineage(
|
||||
[
|
||||
{ worktreeId: 'first', depth: 0 },
|
||||
{ worktreeId: 'first-child', depth: 1 },
|
||||
{ worktreeId: 'second', depth: 0 },
|
||||
{ worktreeId: 'second-child', depth: 1 }
|
||||
],
|
||||
['first', 'second']
|
||||
)
|
||||
).toEqual(['first', 'first-child', 'second', 'second-child'])
|
||||
})
|
||||
|
||||
it('emits each absent selected id once', () => {
|
||||
expect(
|
||||
expandDraggedWorktreeIdsForVisibleLineage(
|
||||
[{ worktreeId: 'row', depth: 0 }],
|
||||
['gone', 'row', 'gone']
|
||||
)
|
||||
).toEqual(['row', 'gone'])
|
||||
})
|
||||
})
|
||||
|
||||
describe('moveWorktreeIdsWithinGroup', () => {
|
||||
|
||||
@@ -41,17 +41,18 @@ export function expandDraggedWorktreeIdsForVisibleLineage(
|
||||
const expandedSet = new Set(draggedIds)
|
||||
const rowIdSet = new Set(rows.map((row) => row.worktreeId))
|
||||
|
||||
for (let index = 0; index < rows.length; index++) {
|
||||
const row = rows[index]!
|
||||
if (!draggedSet.has(row.worktreeId)) {
|
||||
continue
|
||||
let ancestorDepth: number | undefined
|
||||
for (const row of rows) {
|
||||
const depth = row.depth
|
||||
if (ancestorDepth !== undefined && depth <= ancestorDepth) {
|
||||
ancestorDepth = undefined
|
||||
}
|
||||
for (let cursor = index + 1; cursor < rows.length; cursor++) {
|
||||
const child = rows[cursor]!
|
||||
if (child.depth <= row.depth) {
|
||||
break
|
||||
}
|
||||
expandedSet.add(child.worktreeId)
|
||||
if (ancestorDepth !== undefined) {
|
||||
expandedSet.add(row.worktreeId)
|
||||
}
|
||||
// Nested selections are already covered; NaN preserves an unterminated legacy scan.
|
||||
if (draggedSet.has(row.worktreeId) && (ancestorDepth === undefined || Number.isNaN(depth))) {
|
||||
ancestorDepth = depth
|
||||
}
|
||||
}
|
||||
|
||||
@@ -62,8 +63,9 @@ export function expandDraggedWorktreeIdsForVisibleLineage(
|
||||
}
|
||||
}
|
||||
for (const id of draggedIds) {
|
||||
if (!rowIdSet.has(id) && !expandedIds.includes(id)) {
|
||||
if (!rowIdSet.has(id)) {
|
||||
expandedIds.push(id)
|
||||
rowIdSet.add(id)
|
||||
}
|
||||
}
|
||||
return expandedIds
|
||||
|
||||
Reference in New Issue
Block a user