/** * Query iterators — boolean posting-list operations over a segment snapshot. * * Primitives: * - SegmentPostingIter — wraps a single segment's lazy posting iterator; * supports next() and seek(docId). * - MultiSegmentIter — k-way merge of SegmentPostingIters for one term, * emitting (docId, tf) in docId order. * - andQuery — zigzag merge of MultiSegmentIters; yields only docIds * present in ALL term iterators. * - orQuery — k-way union of MultiSegmentIters; yields every docId * present in ANY term iterator, accumulating tf per term. * * All iterators are lazy — no postings are decoded until next()/seek() is called. * Tombstoned doc IDs are filtered at the MultiSegmentIter level. */ import type { SegmentReader } from "./segment.js"; import type { Posting } from "./codec.js"; export interface QueryPosting { docId: number; /** Per-term tf values, keyed by term (for BM25 scoring layer). */ tfs: Map; /** * Index of the segment that owns this docId (into the segments[] array passed * to andQuery/orQuery). Enables O(1) docLen lookup in the scoring layer * instead of scanning all segments. */ segIndex: number; } /** * Wraps a segment's lazy posting iterator for one term. * Caches the current posting so seek() can avoid re-decoding from scratch * for forward seeks (which is the common case in zigzag/merge algorithms). */ export declare class SegmentPostingIter { private readonly iter; private current; private done; constructor(iter: Iterator); get docId(): number | null; get tf(): number; get isExhausted(): boolean; /** Advance to the next posting. */ advance(): void; /** * Advance until docId >= target. Since posting lists are sorted, this is * a linear scan from the current position — O(k) where k is the skip distance. * (v0.2+ can add skip lists for O(log n) seeks.) */ seek(target: number): void; } /** Build the union of all tombstone sets across segments for O(1) lookup. */ export declare function buildTombstoneSet(segments: readonly SegmentReader[]): Set; /** * Merges per-segment SegmentPostingIters for a single term by docId order. * Uses a MinHeap (O(log K) per step) instead of a linear scan (O(K)). * Tombstoned docIds (from the provided set) are skipped transparently. */ export declare class MultiSegmentIter { readonly term: string; private readonly tombstones; private readonly heap; /** All iters, indexed by segIndex — needed for seek(). */ private readonly iters; constructor(term: string, segments: readonly SegmentReader[], tombstones?: Set); private advancePastTombstones; get isExhausted(): boolean; /** The smallest current docId across all active iterators, or null if exhausted. */ get currentDocId(): number | null; /** * Emit the posting for the current minimum docId, summing tf across any segments * sharing that docId (rare in practice), and advance those iterators. * Returns { docId, tf, segIndex } where segIndex is the segment with the lowest * index that contributed (for O(1) docLen lookup). */ next(): { docId: number; tf: number; segIndex: number; } | null; /** * Seek all iterators to the first docId >= target, rebuilding the heap. * O(K log K) — used by andQuery's zigzag merge. */ seek(target: number): void; } /** * AND query — zigzag merge. * * Iterates over the intersection of all term iterators. At each step: * 1. Find the maximum current docId across all iterators. * 2. Seek all other iterators to that docId. * 3. If all iterators land on the same docId, emit it and advance everyone. * 4. Otherwise, repeat from step 1. * * Returns results in ascending docId order. */ export declare function andQuery(terms: string[], segments: readonly SegmentReader[]): Generator; /** * OR query — k-way union merge. * * Iterates over the union of all term iterators, emitting each unique docId once * with all matching term tfs collected. Results are in ascending docId order. */ export declare function orQuery(terms: string[], segments: readonly SegmentReader[]): Generator; //# sourceMappingURL=query.d.ts.map