export class AdaptiveCache {
    cache;
    options;
    evictionInterval = null;
    constructor(options) {
        const { maxEntries, defaultTTL = 300000, // 5 minutes
        hotThreshold = 10, coldEvictionRatio = 0.5, } = options;
        this.options = {
            maxEntries,
            defaultTTL,
            hotThreshold,
            coldEvictionRatio,
        };
        this.cache = new Map();
        this.startEviction();
    }
    /**
     * Get value from cache with adaptive TTL
     */
    get(key) {
        const entry = this.cache.get(key);
        if (!entry)
            return null;
        // Check if expired
        const age = Date.now() - entry.lastModified.getTime();
        const ttl = this.getAdaptiveTTL(entry);
        if (age > ttl) {
            this.cache.delete(key);
            return null;
        }
        // Update access metadata + LRU order
        entry.lastAccessed = new Date();
        entry.usageCount++;
        this.cache.delete(key);
        this.cache.set(key, entry);
        return entry.value;
    }
    /**
     * Set value in cache
     */
    set(key, value, priority = 1) {
        if (this.cache.has(key)) {
            this.cache.delete(key);
        }
        else if (this.cache.size >= this.options.maxEntries) {
            this.evict();
        }
        this.cache.set(key, {
            value,
            lastAccessed: new Date(),
            lastModified: new Date(),
            usageCount: 0,
            priority,
        });
    }
    /**
     * Delete value from cache
     */
    delete(key) {
        return this.cache.delete(key);
    }
    /**
     * Clear all entries
     */
    clear() {
        this.cache.clear();
    }
    /**
     * Get cache size
     */
    get size() {
        return this.cache.size;
    }
    /**
     * Calculate adaptive TTL based on usage patterns
     */
    getAdaptiveTTL(entry) {
        if (entry.usageCount >= this.options.hotThreshold) {
            return this.options.defaultTTL * 12; // 1 hour for hot entries
        }
        if (entry.usageCount >= this.options.hotThreshold / 2) {
            return this.options.defaultTTL * 3; // 15 minutes for warm entries
        }
        return this.options.defaultTTL; // 5 minutes default
    }
    /**
     * Evict entries based on priority and access patterns
     */
    evict() {
        const toRemove = Math.ceil(this.cache.size * 0.3);
        for (let i = 0; i < toRemove; i++) {
            const oldestKey = this.cache.keys().next().value;
            if (oldestKey === undefined)
                return;
            this.cache.delete(oldestKey);
        }
    }
    /**
     * Start periodic eviction
     */
    startEviction() {
        this.evictionInterval = setInterval(() => {
            this.evict();
        }, 60000); // Run every minute
        // Prevent blocking Node.js process exit
        if (this.evictionInterval.unref)
            this.evictionInterval.unref();
    }
    /**
     * Stop eviction interval
     */
    stop() {
        if (this.evictionInterval) {
            clearInterval(this.evictionInterval);
            this.evictionInterval = null;
        }
    }
}
/**
 * Create a cache instance with common defaults for pattern matching
 */
export function createPatternCache(maxEntries = 100) {
    return new AdaptiveCache({
        maxEntries,
        defaultTTL: 300000, // 5 minutes
        hotThreshold: 10,
        coldEvictionRatio: 0.5,
    });
}
//# sourceMappingURL=adaptive-cache.js.map