import { Nullable } from '@thermopylae/core.declarations';
import { DoublyLinkedListNode } from '../list/doubly-linked';
import { LinkedList } from '../list/interface';
import { BucketList } from './interface';
/**
 * @private
 */
declare const BUCKET_HEADER_SYM: unique symbol;
/**
 * @private
 */
interface BucketEntryNode<BucketEntry> extends DoublyLinkedListNode<BucketEntryNode<BucketEntry>> {
    [BUCKET_HEADER_SYM]: BucketHeaderNode<BucketEntry>;
}
/**
 * @private
 */
interface BucketHeaderNode<BucketEntry> extends DoublyLinkedListNode<BucketHeaderNode<BucketEntry>> {
    id: number;
    bucket: LinkedList<BucketEntry>;
}
/**
 * Data structure which keeps a list of ordered buckets by their id's.
 *
 * @private
 */
declare class OrderedBucketList<BucketEntry extends BucketEntryNode<BucketEntry>> implements BucketList<number, BucketEntry> {
    private readonly buckets;
    constructor();
    /**
     * Get the first bucket header.
     */
    get head(): Nullable<BucketHeaderNode<BucketEntry>>;
    /**
     * Get the last bucket header.
     */
    get tail(): Nullable<BucketHeaderNode<BucketEntry>>;
    /**
     * @inheritDoc
     */
    get numberOfBuckets(): number;
    /**
     * Get total number of entries from ordered bucket list.
     */
    get size(): number;
    /**
     * @inheritDoc
     */
    has(inTheBucketId: number, entry: BucketEntry): boolean;
    /**
     * Add *entry* into *bucketId*. <br/>
     * This operation has **O(N) complexity in worst case**, because it stats search of the *bucketId* from the list head.
     * Therefore, is recommended to add entries to *bucketId* closer to the head, to reduce search time.
     *
     * @param bucketId		Id of the bucket where *entry* needs to be inserted.
     * @param entry			Entry to be added.
     */
    add(bucketId: number, entry: BucketEntry): void;
    /**
     * Move *entry* from it's current bucket into new bucket with *toBucketId* id. <br/>
     * The same restrictions apply as in the {@link OrderedBucketList.add} method.
     * Therefore, it's recommended that *toBucketId* being as closer as possible to entry's current bucked id.
     *
     * @param _fromBucketId	**Ignored parameter**.
     * @param toBucketId	Id of the bucket where entry needs to be moved.
     * @param entry			Entry to be moved.
     */
    move(_fromBucketId: number, toBucketId: number, entry: BucketEntry): void;
    /**
     * Removes entry from ordered bucket list. This operation has O(1) complexity.
     *
     * @param _fromBucketId		**Ignored parameter**.
     * @param entry				Entry to be removed.
     */
    remove(_fromBucketId: number, entry: BucketEntry): void;
    /**
     * Clear entries from ordered bucket list.
     */
    clear(): void;
    /**
     * Get the id of the bucket where *entry* currently resides.
     *
     * @param entry		Queried entry.
     */
    static getBucketId<Entry extends BucketEntryNode<Entry>>(entry: Entry): number;
    private getInsertionBucket;
    private removeEntryFromBucketHeader;
    private static addEntryToBucketHeader;
}
export { OrderedBucketList, BucketEntryNode, BUCKET_HEADER_SYM };
