import { Token } from '@rimbu/base';
import { EmptyBase, NonEmptyBase } from '@rimbu/collection-types/map-custom';
import { type ArrayNonEmpty, OptLazy, OptLazyOr, type RelatedTo, type ToJSON, TraverseState, Update } from '@rimbu/common';
import type { List } from '@rimbu/list';
import { Stream, type StreamSource } from '@rimbu/stream';
import type { HashMap } from '@rimbu/hashed/map';
import type { HashMapContext } from '@rimbu/hashed/map-custom';
export declare class HashMapEmpty<K = any, V = any> extends EmptyBase implements HashMap<K, V> {
    readonly context: HashMapContext<K>;
    _NonEmptyType: HashMap.NonEmpty<K, V>;
    constructor(context: HashMapContext<K>);
    streamKeys(): Stream<K>;
    streamValues(): Stream<V>;
    get<_, O>(key: K, otherwise?: OptLazy<O>): O;
    hasKey(): false;
    set(key: K, value: V): HashMap.NonEmpty<K, V>;
    addEntry(entry: readonly [K, V]): HashMap.NonEmpty<K, V>;
    addEntries(entries: StreamSource<readonly [K, V]>): HashMap.NonEmpty<K, V>;
    removeKeyAndGet(): undefined;
    removeKey(): HashMap<K, V>;
    removeKeys(): HashMap<K, V>;
    modifyAt(atKey: K, options: {
        ifNew?: OptLazyOr<V, Token>;
    }): HashMap<K, V>;
    mapValues<V2>(): HashMap<K, V2>;
    updateAt(): HashMap<K, V>;
    toBuilder(): HashMap.Builder<K, V>;
    toString(): string;
    toJSON(): ToJSON<(readonly [K, V])[]>;
}
export declare abstract class HashMapNonEmptyBase<K, V> extends NonEmptyBase<readonly [K, V]> implements HashMap.NonEmpty<K, V> {
    _NonEmptyType: HashMap.NonEmpty<K, V>;
    abstract get context(): HashMapContext<K>;
    abstract get size(): number;
    abstract get<UK, O>(key: RelatedTo<K, UK>, otherwise?: OptLazy<O>): V | O;
    abstract addEntry(entry: readonly [K, V], hash?: number): HashMap.NonEmpty<K, V>;
    abstract forEach(f: (entry: readonly [K, V], index: number, halt: () => void) => void, options?: {
        state?: TraverseState;
    }): void;
    abstract modifyAt(atKey: K, options: {
        ifNew?: OptLazyOr<V, Token>;
        ifExists?: ((currentEntry: V, remove: Token) => V | Token) | V;
    }): HashMap<K, V> | any;
    abstract mapValues<V2>(mapFun: (value: V, key: K) => V2): HashMap.NonEmpty<K, V2>;
    abstract toArray(): ArrayNonEmpty<readonly [K, V]>;
    asNormal(): this;
    streamKeys(): Stream.NonEmpty<K>;
    streamValues(): Stream.NonEmpty<V>;
    hasKey<U>(key: RelatedTo<K, U>): boolean;
    set(key: K, value: V): HashMap.NonEmpty<K, V>;
    addEntries(entries: StreamSource<readonly [K, V]>): HashMap.NonEmpty<K, V>;
    removeKeys<UK>(keys: StreamSource<RelatedTo<K, UK>>): HashMap<K, V>;
    updateAt<UK>(key: RelatedTo<K, UK>, update: Update<V>): HashMap.NonEmpty<K, V>;
    removeKey<UK>(key: RelatedTo<K, UK>): HashMap<K, V>;
    removeKeyAndGet<UK>(key: RelatedTo<K, UK>): [HashMap<K, V>, V] | undefined;
    filter(pred: (entry: readonly [K, V], index: number, halt: () => void) => boolean, options?: {
        negate?: boolean;
    }): HashMap<K, V>;
    toBuilder(): HashMap.Builder<K, V>;
    toString(): string;
    toJSON(): ToJSON<(readonly [K, V])[]>;
}
export type MapEntrySet<K, V> = HashMapBlock<K, V> | HashMapCollision<K, V>;
export declare class HashMapBlock<K, V> extends HashMapNonEmptyBase<K, V> {
    readonly context: HashMapContext<K>;
    readonly entries: readonly (readonly [K, V])[] | null;
    readonly entrySets: readonly MapEntrySet<K, V>[] | null;
    readonly size: number;
    readonly level: number;
    constructor(context: HashMapContext<K>, entries: readonly (readonly [K, V])[] | null, entrySets: readonly MapEntrySet<K, V>[] | null, size: number, level: number);
    copy(entries?: readonly (readonly [K, V])[] | null, entrySets?: readonly MapEntrySet<K, V>[] | null, size?: number): HashMapBlock<K, V>;
    stream(): Stream.NonEmpty<readonly [K, V]>;
    get<UK, O>(key: RelatedTo<K, UK>, otherwise?: OptLazy<O>, hash?: number): V | O;
    addEntry(entry: readonly [K, V], hash?: number): HashMap<K, V> | any;
    modifyAt(atKey: K, options: {
        ifNew?: OptLazyOr<V, Token>;
        ifExists?: ((currentEntry: V, remove: Token) => V | Token) | V;
    }, atKeyHash?: number): HashMap<K, V>;
    forEach(f: (entry: readonly [K, V], index: number, halt: () => void) => void, options?: {
        state?: TraverseState;
    }): void;
    mapValues<V2>(mapFun: (value: V, key: K) => V2): HashMap.NonEmpty<K, V2>;
    toArray(): ArrayNonEmpty<[K, V]>;
}
export declare class HashMapCollision<K, V> extends HashMapNonEmptyBase<K, V> {
    readonly context: HashMapContext<K>;
    readonly entries: List.NonEmpty<readonly [K, V]>;
    constructor(context: HashMapContext<K>, entries: List.NonEmpty<readonly [K, V]>);
    get size(): number;
    copy(entries?: List.NonEmpty<readonly [K, V]>): HashMapCollision<K, V>;
    stream(): Stream.NonEmpty<readonly [K, V]>;
    get<U, O>(key: RelatedTo<K, U>, otherwise?: OptLazy<O>, keyHash?: number): V | O;
    addEntry(entry: readonly [K, V], hash?: number): HashMapCollision<K, V>;
    modifyAt(atKey: K, options: {
        ifNew?: OptLazyOr<V, Token>;
        ifExists?: ((currentValue: V, remove: Token) => V | Token) | V;
    }, atKeyHash?: number): HashMap<K, V> | any;
    forEach(f: (entry: readonly [K, V], index: number, halt: () => void) => void, options?: {
        state?: TraverseState;
    }): void;
    mapValues<V2>(mapFun: (value: V, key: K) => V2): HashMap.NonEmpty<K, V2>;
    toArray(): ArrayNonEmpty<readonly [K, V]>;
}
