export type FractionalIndex = string;
export type IndexedValue<V> = [V, FractionalIndex];
export declare function indexedValue<V>(value: V, index: FractionalIndex): IndexedValue<V>;
export declare function getValue<V>(indexedVal: IndexedValue<V>): V;
export declare function getIndex<V>(indexedVal: IndexedValue<V>): FractionalIndex;
/**
 * Creates a comparator for [key, value] tuples that first compares values,
 * then uses the row key as a stable tie-breaker.
 */
export declare function createKeyedComparator<K extends string | number, T>(comparator: (a: T, b: T) => number): (a: [K, T], b: [K, T]) => number;
export type TopKChanges<V> = {
    /** Indicates which element moves into the topK (if any) */
    moveIn: IndexedValue<V> | null;
    /** Indicates which element moves out of the topK (if any) */
    moveOut: IndexedValue<V> | null;
};
export type TopKMoveChanges<V> = {
    /** Flag that marks whether there were any changes to the topK */
    changes: boolean;
    /** Indicates which elements move into the topK (if any) */
    moveIns: Array<IndexedValue<V>>;
    /** Indicates which elements move out of the topK (if any) */
    moveOuts: Array<IndexedValue<V>>;
};
/**
 * A topK data structure that supports insertions and deletions
 * and returns changes to the topK.
 */
export interface TopK<V> {
    size: number;
    insert: (value: V) => TopKChanges<V>;
    delete: (value: V) => TopKChanges<V>;
}
/**
 * Implementation of a topK data structure.
 * Uses a sorted array internally to store the values and keeps a topK window over that array.
 * Inserts and deletes are O(n) operations because worst case an element is inserted/deleted
 * at the start of the array which causes all the elements to shift to the right/left.
 */
export declare class TopKArray<V> implements TopK<V> {
    #private;
    constructor(offset: number, limit: number, comparator: (a: V, b: V) => number);
    get size(): number;
    /**
     * Moves the topK window
     */
    move({ offset, limit, }: {
        offset?: number;
        limit?: number;
    }): TopKMoveChanges<V>;
    insert(value: V): TopKChanges<V>;
    /**
     * Deletes a value that may or may not be in the topK.
     * IMPORTANT: this assumes that the value is present in the collection
     *            if it's not the case it will remove the element
     *            that is on the position where the provided `value` would be.
     */
    delete(value: V): TopKChanges<V>;
}
