mirror of
https://github.com/stablyai/orca.git
synced 2026-09-22 08:02:28 +00:00
perf: cache terminal tab lookup per tab array (#3938)
This commit is contained in:
@@ -88,6 +88,7 @@ import {
|
||||
applyTerminalPaneAttentionToManager,
|
||||
subscribeTerminalPaneAttention
|
||||
} from './terminal-pane-attention-subscriptions'
|
||||
import { getCachedTerminalTabForWorktree } from './terminal-tab-lookup'
|
||||
|
||||
type TerminalPaneProps = {
|
||||
tabId: string
|
||||
@@ -335,8 +336,8 @@ export default function TerminalPane({
|
||||
)
|
||||
const clearCodexRestartNotice = useAppStore((store) => store.clearCodexRestartNotice)
|
||||
const savedLayout = useAppStore((store) => store.terminalLayoutsByTabId[tabId] ?? EMPTY_LAYOUT)
|
||||
const terminalTab = useAppStore(
|
||||
(store) => (store.tabsByWorktree[worktreeId] ?? []).find((tab) => tab.id === tabId) ?? null
|
||||
const terminalTab = useAppStore((store) =>
|
||||
getCachedTerminalTabForWorktree(store.tabsByWorktree, worktreeId, tabId)
|
||||
)
|
||||
const setTabLayout = useAppStore((store) => store.setTabLayout)
|
||||
const restoredLayout = useMemo(
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
import { describe, expect, it, vi } from 'vitest'
|
||||
import type { TerminalTab } from '../../../../shared/types'
|
||||
import { getCachedTerminalTabForWorktree } from './terminal-tab-lookup'
|
||||
|
||||
function makeTab(id: string): TerminalTab {
|
||||
return {
|
||||
id,
|
||||
ptyId: null,
|
||||
worktreeId: 'wt-1',
|
||||
title: id,
|
||||
customTitle: null,
|
||||
color: null,
|
||||
sortOrder: 0,
|
||||
createdAt: 0
|
||||
}
|
||||
}
|
||||
|
||||
function iterableTabs(tabs: TerminalTab[]): {
|
||||
value: TerminalTab[]
|
||||
iterator: ReturnType<typeof vi.fn>
|
||||
} {
|
||||
const iterator = vi.fn(function* () {
|
||||
yield* tabs
|
||||
})
|
||||
return {
|
||||
value: { [Symbol.iterator]: iterator } as unknown as TerminalTab[],
|
||||
iterator
|
||||
}
|
||||
}
|
||||
|
||||
describe('getCachedTerminalTabForWorktree', () => {
|
||||
it('reuses the tab lookup while the worktree tab array is unchanged', () => {
|
||||
const tabs = Array.from({ length: 200 }, (_, index) => makeTab(`tab-${index}`))
|
||||
const { value, iterator } = iterableTabs(tabs)
|
||||
const tabsByWorktree = { 'wt-1': value }
|
||||
|
||||
expect(getCachedTerminalTabForWorktree(tabsByWorktree, 'wt-1', 'tab-199')).toBe(tabs[199])
|
||||
expect(getCachedTerminalTabForWorktree(tabsByWorktree, 'wt-1', 'tab-0')).toBe(tabs[0])
|
||||
|
||||
expect(iterator).toHaveBeenCalledTimes(1)
|
||||
})
|
||||
|
||||
it('rebuilds the lookup when the tab array reference changes', () => {
|
||||
const first = iterableTabs([makeTab('tab-1')])
|
||||
const second = iterableTabs([makeTab('tab-2')])
|
||||
|
||||
expect(getCachedTerminalTabForWorktree({ 'wt-1': first.value }, 'wt-1', 'tab-1')?.id).toBe(
|
||||
'tab-1'
|
||||
)
|
||||
expect(getCachedTerminalTabForWorktree({ 'wt-1': second.value }, 'wt-1', 'tab-2')?.id).toBe(
|
||||
'tab-2'
|
||||
)
|
||||
|
||||
expect(first.iterator).toHaveBeenCalledTimes(1)
|
||||
expect(second.iterator).toHaveBeenCalledTimes(1)
|
||||
})
|
||||
})
|
||||
@@ -0,0 +1,25 @@
|
||||
import type { TerminalTab } from '../../../../shared/types'
|
||||
|
||||
const terminalTabLookupByArray = new WeakMap<readonly TerminalTab[], Map<string, TerminalTab>>()
|
||||
|
||||
export function getCachedTerminalTabForWorktree(
|
||||
tabsByWorktree: Record<string, TerminalTab[]>,
|
||||
worktreeId: string,
|
||||
tabId: string
|
||||
): TerminalTab | null {
|
||||
const tabs = tabsByWorktree[worktreeId]
|
||||
if (!tabs) {
|
||||
return null
|
||||
}
|
||||
let lookup = terminalTabLookupByArray.get(tabs)
|
||||
if (!lookup) {
|
||||
// Why: every mounted TerminalPane asks for its own tab on store updates.
|
||||
// Build the per-array lookup once so 200 panes do not repeat the same scan.
|
||||
lookup = new Map()
|
||||
for (const tab of tabs) {
|
||||
lookup.set(tab.id, tab)
|
||||
}
|
||||
terminalTabLookupByArray.set(tabs, lookup)
|
||||
}
|
||||
return lookup.get(tabId) ?? null
|
||||
}
|
||||
Reference in New Issue
Block a user