mirror of
https://github.com/stablyai/orca.git
synced 2026-10-09 08:02:35 +00:00
perf(terminal): scan synchronized markers in linear work (#23015)
This commit is contained in:
+80
@@ -0,0 +1,80 @@
|
||||
import { afterEach, describe, expect, it, vi } from 'vitest'
|
||||
import {
|
||||
scanSynchronizedForegroundOutput,
|
||||
SYNCHRONIZED_OUTPUT_START_SEQUENCE as start,
|
||||
SYNCHRONIZED_OUTPUT_END_SEQUENCE as end
|
||||
} from './foreground-output-scan'
|
||||
|
||||
afterEach(() => vi.restoreAllMocks())
|
||||
|
||||
describe('foreground synchronized output scan', () => {
|
||||
it.each([start, end])('bounds searched characters for a flood of %j markers', (marker) => {
|
||||
const data = marker.repeat(8192)
|
||||
const originalIndexOf = String.prototype.indexOf
|
||||
let searchedCharacters = 0
|
||||
const spy = vi.spyOn(String.prototype, 'indexOf').mockImplementation(function (
|
||||
this: string,
|
||||
search: string,
|
||||
position = 0
|
||||
): number {
|
||||
const result = originalIndexOf.call(this, search, position)
|
||||
if (this === data && (search === start || search === end)) {
|
||||
searchedCharacters += (result < 0 ? data.length : result + search.length) - position
|
||||
}
|
||||
return result
|
||||
})
|
||||
const result = scanSynchronizedForegroundOutput(data, '', false)
|
||||
spy.mockRestore()
|
||||
console.info(JSON.stringify({ markers: 8192, chars: data.length, searchedCharacters }))
|
||||
expect(result).toEqual({
|
||||
started: marker === start,
|
||||
ended: marker === end,
|
||||
active: marker === start,
|
||||
markerTail: data.slice(-7)
|
||||
})
|
||||
expect(searchedCharacters).toBeLessThanOrEqual(data.length * 2)
|
||||
})
|
||||
|
||||
it('preserves the last marker and records both transitions in the current chunk', () => {
|
||||
expect(scanSynchronizedForegroundOutput(`${end}paint${start}`, '', true)).toEqual({
|
||||
started: true,
|
||||
ended: true,
|
||||
active: true,
|
||||
markerTail: start.slice(1)
|
||||
})
|
||||
expect(scanSynchronizedForegroundOutput(`${start}paint${end}`, '', false)).toEqual({
|
||||
started: true,
|
||||
ended: true,
|
||||
active: false,
|
||||
markerTail: end.slice(1)
|
||||
})
|
||||
})
|
||||
|
||||
it.each([start, end])('recognizes %j at every socket split', (marker) => {
|
||||
for (let split = 1; split < marker.length; split++) {
|
||||
const first = scanSynchronizedForegroundOutput(marker.slice(0, split), '', marker === end)
|
||||
const second = scanSynchronizedForegroundOutput(
|
||||
marker.slice(split),
|
||||
first.markerTail,
|
||||
first.active
|
||||
)
|
||||
expect(second).toEqual({
|
||||
started: marker === start,
|
||||
ended: marker === end,
|
||||
active: marker === start,
|
||||
markerTail: marker.slice(1)
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
it('leaves the latch unchanged for empty output and malformed lookalikes', () => {
|
||||
for (const data of ['', 'ordinary output', '\x1b[?2026x'.repeat(2048)]) {
|
||||
expect(scanSynchronizedForegroundOutput(data, '', true)).toEqual({
|
||||
started: false,
|
||||
ended: false,
|
||||
active: true,
|
||||
markerTail: data.slice(-7)
|
||||
})
|
||||
}
|
||||
})
|
||||
})
|
||||
@@ -58,27 +58,30 @@ export function scanSynchronizedForegroundOutput(
|
||||
let active = wasActive
|
||||
let started = false
|
||||
let ended = false
|
||||
let offset = 0
|
||||
let startIndex = scanData.indexOf(SYNCHRONIZED_OUTPUT_START_SEQUENCE)
|
||||
let endIndex = scanData.indexOf(SYNCHRONIZED_OUTPUT_END_SEQUENCE)
|
||||
|
||||
while (offset < scanData.length) {
|
||||
const startIndex = scanData.indexOf(SYNCHRONIZED_OUTPUT_START_SEQUENCE, offset)
|
||||
const endIndex = scanData.indexOf(SYNCHRONIZED_OUTPUT_END_SEQUENCE, offset)
|
||||
if (startIndex === -1 && endIndex === -1) {
|
||||
break
|
||||
}
|
||||
// Each marker search advances independently, so a missing counterpart is scanned only once.
|
||||
while (startIndex !== -1 || endIndex !== -1) {
|
||||
if (endIndex !== -1 && (startIndex === -1 || endIndex < startIndex)) {
|
||||
active = false
|
||||
if (endIndex + SYNCHRONIZED_OUTPUT_END_SEQUENCE.length > currentChunkStartIndex) {
|
||||
ended = true
|
||||
}
|
||||
offset = endIndex + SYNCHRONIZED_OUTPUT_END_SEQUENCE.length
|
||||
endIndex = scanData.indexOf(
|
||||
SYNCHRONIZED_OUTPUT_END_SEQUENCE,
|
||||
endIndex + SYNCHRONIZED_OUTPUT_END_SEQUENCE.length
|
||||
)
|
||||
continue
|
||||
}
|
||||
active = true
|
||||
if (startIndex + SYNCHRONIZED_OUTPUT_START_SEQUENCE.length > currentChunkStartIndex) {
|
||||
started = true
|
||||
}
|
||||
offset = startIndex + SYNCHRONIZED_OUTPUT_START_SEQUENCE.length
|
||||
startIndex = scanData.indexOf(
|
||||
SYNCHRONIZED_OUTPUT_START_SEQUENCE,
|
||||
startIndex + SYNCHRONIZED_OUTPUT_START_SEQUENCE.length
|
||||
)
|
||||
}
|
||||
|
||||
return {
|
||||
|
||||
Reference in New Issue
Block a user