"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.LruMap = void 0;
const SizedMap_1 = require("./SizedMap");
class LruMap extends SizedMap_1.SizedMap {
    has(key) {
        const node = this.map.get(key);
        if (node) {
            this.removeNode(node);
            this.moveToTop(node);
            return true;
        }
        return false;
    }
    get(key, _default) {
        const node = this.map.get(key);
        if (node) {
            this.removeNode(node);
            this.moveToTop(node);
            return node.value;
        }
        return _default;
    }
    set(key, value) {
        let node = this.map.get(key);
        if (node) {
            node.value = value;
            this.removeNode(node);
            this.moveToTop(node);
        }
        else {
            node = {
                key: key,
                value: value,
            };
            if (this.isFull()) {
                this.delete(this.tail.key);
            }
            this.moveToTop(node);
            this.map.set(key, node);
        }
        return this;
    }
    delete(key) {
        const node = this.map.get(key);
        if (node) {
            this.removeNode(node);
            return super.delete(key);
        }
        return false;
    }
    clear() {
        this.head = this.tail = undefined;
        super.clear();
    }
    moveToTop(node) {
        node.next = this.head;
        node.previous = undefined;
        if (this.head) {
            this.head.previous = node;
        }
        this.head = node;
        if (!this.tail) {
            this.tail = this.head;
        }
    }
    removeNode(node) {
        if (node.previous) {
            node.previous.next = node.next;
        }
        else {
            this.head = node.next;
        }
        if (node.next) {
            node.next.previous = node.previous;
        }
        else {
            this.tail = node.previous;
        }
    }
}
exports.LruMap = LruMap;
