/** * External merge sort — sort a stream of records larger than RAM. * * Foundation for Engine 3's scalable uniqueness: to guarantee no duplicate * tuples across billions of rows you must sort them so equal tuples become * adjacent, and that sort has to run in bounded memory. Classic two-phase * algorithm: * 1. Read the input in chunks of `chunkSize` records, sort each chunk in * RAM, and write it to a temp "run" file. → K sorted runs on disk. * 2. K-way merge the runs with a min-heap of their current heads, streaming * the fully-sorted result. Only K record heads live in RAM at once. * * Small inputs (≤ one chunk) never touch disk. Deterministic: the comparator * fully orders records (ties broken by run index during the merge). * * Records must not contain the record separator `\n`. */ export interface ExternalSortOptions { /** Records held in RAM per run (Phase 1). Smaller → more, smaller runs. */ readonly chunkSize?: number | undefined; /** Directory for temp run files (default: OS temp). */ readonly tmpDir?: string | undefined; /** Total order over records. Default: byte-wise (`<`/`>`). */ readonly compare?: ((a: string, b: string) => number) | undefined; } /** Streaming line reader over a run file — bounded memory, one partial line held. */ /** * Reads a run file back one record at a time, in bounded memory. * * Exported because the sort is not the only thing that writes a file of records * and needs it back: the uniq repair keeps the tuples it has already computed * rather than computing them again. */ export declare class RunReader { private readonly fd; private readonly buffer; private pending; private eof; constructor(path: string); /** Next record, or undefined at end of file. */ next(): string | undefined; close(): void; } /** * Writes records to a file one at a time, buffered. * * `writeRun` below takes an array it already holds; this one is for a caller * that has a stream and does not want to hold it. */ export declare class RunWriter { private readonly fd; private buffer; constructor(path: string); write(record: string): void; close(): void; } /** * Merge already-sorted run files into one sorted stream. * * Phase two of the sort, on its own, because the runs do not have to have come * from phase one. Several threads can each sort their own slice of the rows and * hand the files over — the merge neither knows nor cares who wrote them, only * that each is sorted. That is what lets the tuple scan use every core: the * expensive part is computing and sorting the rows, and it splits; the merge is * cheap and stays here. * * Only one record per run lives in memory at a time. */ export declare function mergeRuns(runs: readonly string[], compare?: (a: string, b: string) => number): Generator; /** * Sort `records` into a fully-ordered stream using bounded memory. Yields the * sorted records. Consume the whole generator (temp files are cleaned up when * it finishes or is returned early). */ export declare function externalSort(records: Iterable, options?: ExternalSortOptions): Generator; //# sourceMappingURL=external-sort.d.ts.map