"use strict";
Object.defineProperty(exports, "__esModule", {
    value: true
});
Object.defineProperty(exports, "MultiLevelCache", {
    enumerable: true,
    get: function() {
        return MultiLevelCache;
    }
});
function _define_property(obj, key, value) {
    if (key in obj) {
        Object.defineProperty(obj, key, {
            value: value,
            enumerable: true,
            configurable: true,
            writable: true
        });
    } else {
        obj[key] = value;
    }
    return obj;
}
let MultiLevelCache = class MultiLevelCache {
    /**
   * 将节点移到链表头部（最近使用）
   */ moveToHead(node) {
        const nodeAsUnknown = node;
        if (nodeAsUnknown === this.head) {
            return;
        }
        // 从当前位置移除
        if (node.prev) {
            node.prev.next = node.next;
        }
        if (node.next) {
            node.next.prev = node.prev;
        }
        if (nodeAsUnknown === this.tail) {
            this.tail = node.prev;
        }
        // 移到头部
        node.prev = null;
        node.next = this.head;
        if (this.head) {
            this.head.prev = nodeAsUnknown;
        }
        this.head = nodeAsUnknown;
        if (!this.tail) {
            this.tail = nodeAsUnknown;
        }
    }
    /**
   * 移除尾部节点（最久未使用）
   */ removeTail() {
        if (!this.tail) {
            return;
        }
        const key = this.tail.key;
        this.memoryCache.delete(key);
        if (this.tail.prev) {
            this.tail.prev.next = null;
            this.tail = this.tail.prev;
        } else {
            this.head = null;
            this.tail = null;
        }
    }
    /**
   * 获取缓存
   */ async get(key) {
        // 先检查内存缓存
        const node = this.memoryCache.get(key);
        if (node) {
            const item = node.value;
            if (item.expiresAt > Date.now()) {
                // 移到头部（最近使用）
                this.moveToHead(node);
                return item.data;
            } else {
                // 已过期，删除
                this.memoryCache.delete(key);
                if (node === this.head) {
                    this.head = node.next;
                }
                if (node === this.tail) {
                    this.tail = node.prev;
                }
                if (node.prev) {
                    node.prev.next = node.next;
                }
                if (node.next) {
                    node.next.prev = node.prev;
                }
            }
        }
        // 检查存储缓存
        try {
            const stored = await this.storage.get(key);
            if (stored) {
                const item = JSON.parse(stored);
                if (item.expiresAt > Date.now()) {
                    // 更新内存缓存（使用 LRU）
                    this.setInMemory(key, item);
                    return item.data;
                } else {
                    // 已过期，删除
                    await this.storage.remove(key);
                }
            }
        } catch (error) {
        // 忽略解析错误
        }
        return null;
    }
    /**
   * 在内存中设置缓存（LRU）
   */ setInMemory(key, item) {
        let node = this.memoryCache.get(key);
        if (node) {
            // 更新现有节点
            node.value = item;
            this.moveToHead(node);
        } else {
            // 创建新节点
            node = {
                key,
                value: item,
                prev: null,
                next: this.head
            };
            if (this.head) {
                this.head.prev = node;
            }
            this.head = node;
            if (!this.tail) {
                this.tail = node;
            }
            this.memoryCache.set(key, node);
            // 如果超过最大大小，移除最久未使用的
            if (this.memoryCache.size > this.config.maxSize) {
                this.removeTail();
            }
        }
    }
    /**
   * 设置缓存
   */ async set(key, data, ttl) {
        const expiresAt = Date.now() + (ttl || this.config.defaultTTL);
        const item = {
            data,
            expiresAt,
            createdAt: Date.now()
        };
        // 更新内存缓存（使用 LRU）
        this.setInMemory(key, item);
        // 更新存储缓存
        try {
            await this.storage.set(key, item);
        } catch (error) {
        // 忽略存储错误
        }
    }
    /**
   * 删除缓存
   */ async delete(key) {
        const node = this.memoryCache.get(key);
        if (node) {
            // 从链表中移除
            if (node.prev) {
                node.prev.next = node.next;
            }
            if (node.next) {
                node.next.prev = node.prev;
            }
            if (node === this.head) {
                this.head = node.next;
            }
            if (node === this.tail) {
                this.tail = node.prev;
            }
            this.memoryCache.delete(key);
        }
        try {
            await this.storage.remove(key);
        } catch (error) {
        // 忽略删除错误
        }
    }
    /**
   * 清空缓存
   */ async clear() {
        this.memoryCache.clear();
    // 注意：这里不清空 storage，因为可能包含其他数据
    }
    /**
   * 清理过期项（优化版本：批量删除，减少 DOM 操作）
   */ async cleanup() {
        const now = Date.now();
        const keysToDelete = [];
        const nodesToRemove = [];
        // 批量收集需要删除的项
        for (const [key, node] of this.memoryCache.entries()){
            if (node.value.expiresAt <= now) {
                keysToDelete.push(key);
                nodesToRemove.push(node);
            }
        }
        // 批量删除（优化性能）
        if (keysToDelete.length > 0) {
            // 从链表中移除节点
            for (const node of nodesToRemove){
                if (node.prev) {
                    node.prev.next = node.next;
                }
                if (node.next) {
                    node.next.prev = node.prev;
                }
                if (node === this.head) {
                    this.head = node.next;
                }
                if (node === this.tail) {
                    this.tail = node.prev;
                }
            }
            // 批量删除 Map 中的项
            keysToDelete.forEach((key)=>this.memoryCache.delete(key));
        }
    // 注意：存储缓存的清理由存储系统自己处理（通过过期时间）
    }
    constructor(storage, config = {}){
        _define_property(this, "memoryCache", new Map());
        _define_property(this, "storage", void 0);
        _define_property(this, "config", void 0);
        _define_property(this, "head", null);
        _define_property(this, "tail", null);
        this.storage = storage;
        this.config = {
            defaultTTL: config.defaultTTL ?? 24 * 60 * 60 * 1000,
            maxSize: config.maxSize ?? 100
        };
    }
};

//# sourceMappingURL=cache.js.map