// ─── I/O instrumentation (opt-in, for mcp/bench) ─── // // A process-wide counter of shard reads and parsed bytes, so the benchmark can // report the STRUCTURAL cost of a query (how many pages, how many bytes) next // to its wall time. That matters on a shared box specifically: wall time is only // meaningful when the machine is idle, but read counts and byte counts are // properties of the query plan and hold under any load. // // Off unless MCP_IO_STATS=1, and even then it is two integer adds per read. // // Moved here from mcp/src/source.ts with one change: the enable flag is guarded // so this module can be imported from a browser bundle. `process.env?.X` behind // a `typeof process` check is a dynamic read Next does NOT inline, which is // exactly right for a server-only diagnostic — the browser gets `undefined` and // the counters stay off, rather than the bundle failing on a missing global. export type IoStats = { reads: number; bytes: number }; const IO_STATS_ON = typeof process !== "undefined" && process.env?.MCP_IO_STATS === "1"; const ioTotals: Record = {}; export function recordRead(kind: string, bytes: number): void { if (!IO_STATS_ON) return; const slot = (ioTotals[kind] ??= { reads: 0, bytes: 0 }); slot.reads++; slot.bytes += bytes; } // A snapshot of every counter so far, for diffing across one tool call. export function ioStatsSnapshot(): Record { const out: Record = {}; for (const [k, v] of Object.entries(ioTotals)) out[k] = { ...v }; return out; } export function ioStatsEnabled(): boolean { return IO_STATS_ON; }