import Signal from "../events/signal/Signal";

interface Hashable {
    hash(): number
    equals(other: any): boolean
}

export class Cache<K extends Hashable, V> extends Map<K,V>{
    constructor({
                    maxWeight,
                    keyWeigher,
                    valueWeigher,
                    keyHashFunction,
                    keyEqualityFunction,
                    capacity
                }?: {
        maxWeight?: number,
        keyWeigher?: (key: K) => number,
        valueWeigher?: (value: V) => number,
        keyHashFunction?: (key: K) => number,
        keyEqualityFunction?: (a: K, b: K) => boolean,
        capacity?: number
    })

    readonly onEvicted: Signal<K, V>
    readonly onRemoved: Signal<K, V>
    readonly onSet: Signal<K, V>

    readonly weight: number

    maxWeight: number

    size(): number

    put(k: K, v: V): void

    get(k: K): V | null

    contains(k: K): boolean

    remove(k: K): boolean

    silentRemove(k: K): boolean

    evictOne(): boolean

    clear(): void

    drop(): void

    getOrCompute(key: K, compute: (key: K) => V, compute_context?: any): V

    recomputeWeight(): void

    updateElementWeight(key: K): boolean
}
