export type DistanceMetric = "euclidean" | "cosine"; export interface KDPoint { vector: number[]; payload: T; } export interface KNNResult { point: KDPoint; distance: number; } /** * K-D Tree for efficient nearest-neighbor search over high-dimensional vectors / embeddings. * * Supports: * - Insertion of labeled points * - Lazy (tombstone) removal, physically purged on rebalance() * - k-nearest-neighbor (KNN) search * - Radius search (all points within a given distance) * - Euclidean and cosine distance metrics * - Bulk construction (balanced tree) for best query performance */ export declare class KDTree { private root; private _size; private _tombstones; private readonly distanceFn; readonly dims: number; /** * @param dims Dimensionality of all vectors (must be consistent). * @param metric Distance metric to use. Default: "euclidean". * @param points Optional initial set of points. Builds a balanced tree * in O(n log² n) — prefer this over inserting one-by-one * when you have a large corpus. */ constructor(dims: number, metric?: DistanceMetric, points?: KDPoint[]); /** Total number of live points stored in the tree (excludes tombstoned). */ get size(): number; /** Fraction of physical nodes that are tombstoned (pending removal on next rebalance). */ get tombstoneRatio(): number; /** * Insert a single point. O(log n) average, O(n) worst case on skewed data. * For bulk loading prefer passing points to the constructor. */ insert(point: KDPoint): void; /** * Lazily remove all live points whose payload matches `predicate`. * O(n) traversal, but avoids a full tree rebuild. Call `rebalance()` * periodically (e.g. once tombstoneRatio crosses ~0.25) to reclaim space * and restore optimal query depth. * @returns number of points removed */ remove(predicate: (payload: T) => boolean): number; /** * Find the k nearest live neighbors to `query`. * Returns results sorted by distance ascending. */ knn(query: number[], k: number): KNNResult[]; /** * Nearest single neighbor. Convenience wrapper around knn(query, 1). * Returns null if the tree is empty. */ nearest(query: number[]): KNNResult | null; /** * Return all live points whose distance to `query` is ≤ `radius`, * sorted by distance ascending. */ radiusSearch(query: number[], radius: number): KNNResult[]; /** Collect all live points in the tree (order not guaranteed). */ toArray(): KDPoint[]; /** * Rebuild the tree from its current live points as a balanced tree. * Physically purges tombstones and restores O(log n) query time. */ rebalance(): void; private buildBalanced; private insertNode; private searchKNN; private searchRadius; private collect; private validateVector; private validate; private validateAll; }