Read-ahead per reader; compose passes READ_AHEAD and PERF_TRACE; report fixes

Each user gets an own read-ahead queue, served in turn, so two people reading
at once no longer cancel each other's chapter. The report rounds phase times
and measures the quiet time before a slow storage probe correctly.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
MaashkinoozheandClaude Opus 5.5 committed 2026-10-29 22:51:19 +01:00
1 parent 896726a51b
commit d7d3bf5b2b
6 files changed
+57 -34

No files matched your search

+13
View File
@@ -76,6 +76,19 @@ test('read-ahead reads files in order and a newer chapter replaces the queued on
assert.deepEqual(batches.map(x => [x.tag, x.files, x.skipped]), [['C', 0, 2]]);
});
test('read-ahead keeps one queue per reader and serves them in turn', async () => {
const dir = tmp(), mk = n => { const f = path.join(dir, n); fs.writeFileSync(f, n); return f; };
const order = [], batches = [];
const ahead = new ReadAhead({ concurrency: 1, onBatch: b => batches.push(b) });
const read = ahead.readFile.bind(ahead);
ahead.readFile = f => { order.push(path.basename(f)); return read(f); };
ahead.warm([mk('a1'), mk('a2')], 'A', 'ann');
ahead.warm([mk('b1'), mk('b2')], 'B', 'bob');
await new Promise(r => { const check = () => (batches.length === 2 ? r() : setTimeout(check, 5)); check(); });
assert.deepEqual(order, ['a1', 'b1', 'a2', 'b2']);
assert.ok(batches.every(b => !b.replaced && b.done === 2));
});
test('read-ahead runs the follow-up batch after the current one', async () => {
const dir = tmp(), a = path.join(dir, 'a.jpg'), b = path.join(dir, 'b.jpg');
fs.writeFileSync(a, 'a'); fs.writeFileSync(b, 'bb');