mirror of
https://github.com/stablyai/orca.git
synced 2026-09-21 16:02:20 +00:00
* perf(tooling): reuse directory entry types in source scans
* fix(source-scan): stat DT_UNKNOWN dirents so untyped directories are still walked
`readdirSync(..., { withFileTypes: true })` can hand back a Dirent whose
type the filesystem did not report. For that entry every predicate is
false, so the readdir-type fast path treated a real directory as a file
and silently dropped its subtree from every ratchet guard. Fall back to
`statSync` whenever the entry is neither conclusively a file nor a
directory, keeping the no-stat fast path for ordinary entries.
Also make the two readdir-order assertions in the walk test
order-independent; `scanSourceTree` returns raw readdir order, which
differs on tmpfs.
* test(source-scan): unit-test the stat fallback via an extracted helper
The fabricated-Dirent readdir mock could not satisfy both gates at once:
vi.mocked(readdirSync) resolves to Node's Dirent<NonSharedBuffer> overload, so
the mock needed a type assertion, and #19462's casting gate rejects new ones on
changed lines. Removing the cast then failed tsc.
Extract directoryEntryNeedsStat and test it directly with a structural probe.
No mock, no cast, no top-level await, and the DT_UNKNOWN case is pinned:
removing the fallback fails 'stats an entry whose type readdir could not report'.
---------
Co-authored-by: m4air <m4air@Mac.localdomain>
Co-authored-by: Neil <neil@stably.ai>
64 lines
2.4 KiB
JavaScript
64 lines
2.4 KiB
JavaScript
import assert from 'node:assert/strict'
|
|
import { createHash } from 'node:crypto'
|
|
import { readFileSync } from 'node:fs'
|
|
import { stripTypeScriptTypes } from 'node:module'
|
|
import { resolve } from 'node:path'
|
|
import { performance } from 'node:perf_hooks'
|
|
import { buildCounterbalancedSchedule } from './counterbalanced-benchmark-schedule.mjs'
|
|
import { summarizeBenchmarkSamples } from './benchmark-sample-summary.mjs'
|
|
|
|
// git show <baseline-ref>:src/shared/source-scan/source-tree-scan.ts | node config/scripts/source-tree-walk-benchmark.mjs
|
|
async function load(source) {
|
|
const code = stripTypeScriptTypes(source)
|
|
return (await import(`data:text/javascript;base64,${Buffer.from(code).toString('base64')}`))
|
|
.scanSourceTree
|
|
}
|
|
const baseline = readFileSync(0, 'utf8')
|
|
assert.ok(baseline.includes('function scanSourceTree'), 'Pipe the baseline source into stdin')
|
|
const implementations = {
|
|
before: await load(baseline),
|
|
after: await load(readFileSync('src/shared/source-scan/source-tree-scan.ts', 'utf8'))
|
|
}
|
|
function fingerprint(files) {
|
|
const hash = createHash('sha256')
|
|
for (const file of files) {
|
|
for (const value of [file.path, file.relativePath, file.source]) {
|
|
hash
|
|
.update(String(Buffer.byteLength(value)))
|
|
.update(':')
|
|
.update(value)
|
|
}
|
|
}
|
|
return hash.digest('hex')
|
|
}
|
|
const results = []
|
|
for (const directory of ['src', 'mobile/src', 'cloud/apps']) {
|
|
const root = resolve(directory)
|
|
const original = implementations.before(root)
|
|
const expected = fingerprint(original)
|
|
assert.deepEqual(implementations.after(root), original)
|
|
const samples = { before: [], after: [] }
|
|
for (let warmup = 0; warmup < 2; warmup += 1) {
|
|
for (const run of Object.values(implementations)) {
|
|
run(root)
|
|
}
|
|
}
|
|
for (const pair of buildCounterbalancedSchedule(8, 'before', 'after')) {
|
|
for (const arm of pair) {
|
|
const started = performance.now()
|
|
const files = implementations[arm](root)
|
|
samples[arm].push(performance.now() - started)
|
|
assert.equal(fingerprint(files), expected, `${directory} ${arm} inventory changed`)
|
|
}
|
|
}
|
|
results.push({
|
|
directory,
|
|
files: original.length,
|
|
sourceBytes: original.reduce((bytes, file) => bytes + Buffer.byteLength(file.source), 0),
|
|
fingerprint: expected,
|
|
before: summarizeBenchmarkSamples(samples.before),
|
|
after: summarizeBenchmarkSamples(samples.after)
|
|
})
|
|
}
|
|
console.log(JSON.stringify({ node: process.version, platform: process.platform, results }, null, 2))
|