/** * @copyright Sister Software * @license AGPL-3.0 * @author Teffen Ellis, et al. * @file A fixed-capacity set of 128-bit fingerprints in one flat `Uint32Array`. * * The adapter runner deduplicates by holding every key it has seen. A V8 `Set` refuses its 16,777,217th * entry outright, so the runner capped itself at 10,000,000 keys. Three adapters passed that cap in * `v0.7.0-de-holdout`. The duplicate census over that build measured what the cap costs: of the * 2,491,399 duplicate rows the three adapters wrote, 1,490,992 duplicate a key first seen after the cap. * A membership test on a capped set cannot refuse those rows. * * This holds the keys as fingerprints instead. Each slot uses four 32-bit words and open addressing with linear * probing. The allocation happens once at construction. The entry count is bounded by the array * the caller sized rather than by a V8 limit. A 2^27-slot table holds 57,570,829 keys at load 0.43 in * 2.0 GiB outside the V8 heap. * * **A fingerprint collision drops a legitimate row.** Two distinct keys sharing all 128 bits are read as * one and the second row is dropped. Over 57,847,619 keys the expected number of colliding pairs is * about 4.9e-24, so the table trades that for the 1,490,992 duplicates a capped set admits. A caller * that cannot accept any false drop keeps the `Set`. */ /** * The load factor at which linear probing's expected probe count stays low enough to ignore. * * Above this the table refuses further keys rather than degrading, because a build whose * dedup slows by an order of magnitude partway through reports no cause. */ export declare const FINGERPRINT_MAX_LOAD = 0.7; /** * The largest slot count this accepts, as a base-2 logarithm. * * 2^30 slots hold 751,619,276 keys at the load limit and occupy 16 GiB. * Past that the backing `Uint32Array` exceeds what one allocation can hold on a 30.5 GB host, * A run that asks for it aborts on the allocation rather than on the key that overflowed. */ export declare const MAX_SLOTS_LOG2 = 30; /** * A fingerprint set sized once, holding 128-bit values outside the V8 heap. */ export declare class FingerprintSet { #private; /** * @param slotsLog2 Base-2 logarithm of the slot count, so the mask is exact. * 27 gives 134,217,728 slots in 2.0 GiB. */ constructor(slotsLog2: number); get size(): number; /** * How many keys this table accepts before {@linkcode add} throws. */ get limit(): number; get slots(): number; /** * Bytes the table occupies outside the V8 heap. * They are absent from `--max-old-space-size`. */ get bytes(): number; /** * Add a key's fingerprint. * * @returns `true` when the key is new, `false` when this table already holds its fingerprint. * @throws When the table is at {@linkcode FINGERPRINT_MAX_LOAD}. * A silent degradation would make a build slow down partway through with no cause to read. */ add(key: string): boolean; } //# sourceMappingURL=fingerprints.d.ts.map