/** * Multi-level Cache Manager * * Implements a three-level caching strategy: * - Level 1: Hot cache (most accessed nodes) - RAM (automatically detecting and adjusting in each environment) * - Level 2: Warm cache (recent nodes) - OPFS, Filesystem or S3 depending on environment * - Level 3: Cold storage (all nodes) - OPFS, Filesystem or S3 depending on environment */ import { HNSWNoun, GraphVerb, HNSWVerb } from '../coreTypes.js'; declare global { interface Navigator { deviceMemory?: number; } interface WorkerGlobalScope { storage?: { getDirectory?: () => Promise; [key: string]: any; }; } } type HNSWNode = HNSWNoun; type Edge = GraphVerb; interface CacheStats { hits: number; misses: number; evictions: number; size: number; maxSize: number; hotCacheSize: number; warmCacheSize: number; hotCacheHits: number; hotCacheMisses: number; warmCacheHits: number; warmCacheMisses: number; } /** * Multi-level cache manager for efficient data access */ export declare class CacheManager { private hotCache; private stats; private environment; private warmStorageType; private coldStorageType; private hotCacheMaxSize; private hotCacheEvictionThreshold; private warmCacheTTL; private batchSize; private autoTune; private lastAutoTuneTime; private autoTuneInterval; private storageStatistics; private warmStorage; private coldStorage; private options; /** * Initialize the cache manager * @param options Configuration options */ constructor(options?: { hotCacheMaxSize?: number; hotCacheEvictionThreshold?: number; warmCacheTTL?: number; batchSize?: number; autoTune?: boolean; warmStorage?: any; coldStorage?: any; readOnly?: boolean; environmentConfig?: { node?: { hotCacheMaxSize?: number; hotCacheEvictionThreshold?: number; warmCacheTTL?: number; batchSize?: number; }; browser?: { hotCacheMaxSize?: number; hotCacheEvictionThreshold?: number; warmCacheTTL?: number; batchSize?: number; }; worker?: { hotCacheMaxSize?: number; hotCacheEvictionThreshold?: number; warmCacheTTL?: number; batchSize?: number; }; [key: string]: { hotCacheMaxSize?: number; hotCacheEvictionThreshold?: number; warmCacheTTL?: number; batchSize?: number; } | undefined; }; }); /** * Detect the current environment */ private detectEnvironment; /** * Detect the optimal cache size based on available memory and operating mode * * Enhanced to better handle large datasets in S3 or other storage: * - Increases cache size for read-only mode * - Adjusts based on total dataset size when available * - Provides more aggressive caching for large datasets * - Optimizes memory usage based on environment */ private detectOptimalCacheSize; /** * Async version of detectOptimalCacheSize that uses dynamic imports * to access system information in Node.js environments * * This method provides more accurate memory detection by using * the OS module's dynamic import in Node.js environments */ private detectOptimalCacheSizeAsync; /** * Detects available memory across different environments * * This method uses different techniques to detect memory in: * - Node.js: Uses the OS module with dynamic import * - Browser: Uses performance.memory or navigator.deviceMemory * - Worker: Uses performance.memory if available * * @returns An object with totalMemory and freeMemory in bytes, or null if detection fails */ private detectAvailableMemory; /** * Tune cache parameters based on statistics and environment * This method is called periodically if auto-tuning is enabled * * The auto-tuning process: * 1. Retrieves storage statistics if available * 2. Tunes each parameter based on statistics and environment * 3. Logs the tuned parameters if debug is enabled * * Auto-tuning helps optimize cache performance by adapting to: * - The current environment (Node.js, browser, worker) * - Available system resources (memory, CPU) * - Usage patterns (read-heavy vs. write-heavy workloads) * - Cache efficiency (hit/miss ratios) */ private tuneParameters; /** * Tune hot cache size based on statistics, environment, and operating mode * * The hot cache size is tuned based on: * 1. Available memory in the current environment * 2. Total number of nodes and edges in the system * 3. Cache hit/miss ratio * 4. Operating mode (read-only vs. read-write) * 5. Storage type (S3, filesystem, memory) * * Enhanced algorithm: * - Start with a size based on available memory and operating mode * - For large datasets in S3 or other remote storage, use more aggressive caching * - Adjust based on access patterns (read-heavy vs. write-heavy) * - For read-only mode, prioritize cache size over eviction speed * - Dynamically adjust based on hit/miss ratio and query patterns */ private tuneHotCacheSize; /** * Tune eviction threshold based on statistics * * The eviction threshold determines when items start being evicted from the hot cache. * It is tuned based on: * 1. Cache hit/miss ratio * 2. Operation patterns (read-heavy vs. write-heavy workloads) * 3. Memory pressure and available resources * * Algorithm: * - Start with a default threshold of 0.8 (80% of max size) * - For high hit ratios, increase the threshold to keep more items in cache * - For low hit ratios, decrease the threshold to evict items more aggressively * - For read-heavy workloads, use a higher threshold * - For write-heavy workloads, use a lower threshold * - Under memory pressure, use a lower threshold to conserve resources * * @param cacheStats Optional cache statistics for more adaptive tuning */ private tuneEvictionThreshold; /** * Tune warm cache TTL based on statistics * * The warm cache TTL determines how long items remain in the warm cache. * It is tuned based on: * 1. Update frequency from operation statistics * 2. Warm cache hit/miss ratio * 3. Access patterns and frequency * 4. Available storage resources * * Algorithm: * - Start with a default TTL of 24 hours * - For frequently updated data, use a shorter TTL * - For rarely updated data, use a longer TTL * - For frequently accessed data, use a longer TTL * - For rarely accessed data, use a shorter TTL * - Under storage pressure, use a shorter TTL * * @param cacheStats Optional cache statistics for more adaptive tuning */ private tuneWarmCacheTTL; /** * Tune batch size based on environment, statistics, and operating mode * * The batch size determines how many items are processed in a single batch * for operations like prefetching. It is tuned based on: * 1. Current environment (Node.js, browser, worker) * 2. Available memory * 3. Operation patterns * 4. Cache hit/miss ratio * 5. Operating mode (read-only vs. read-write) * 6. Storage type (S3, filesystem, memory) * 7. Dataset size * 8. Cache efficiency and access patterns * * Enhanced algorithm: * - Start with a default based on the environment * - For large datasets in S3 or other remote storage, use larger batches * - For read-only mode, use larger batches to improve throughput * - Dynamically adjust based on network latency and throughput * - Balance between memory usage and performance * - Adapt to cache hit/miss patterns * * @param cacheStats Optional cache statistics for more adaptive tuning */ private tuneBatchSize; /** * Detect the appropriate warm storage type based on environment */ private detectWarmStorageType; /** * Detect the appropriate cold storage type based on environment */ private detectColdStorageType; /** * Initialize warm storage adapter */ private initializeWarmStorage; /** * Initialize cold storage adapter */ private initializeColdStorage; /** * Get an item from cache, trying each level in order * @param id The item ID * @returns The cached item or null if not found */ get(id: string): Promise; /** * Get an item from warm cache * @param id The item ID * @returns The cached item or null if not found */ private getFromWarmCache; /** * Get an item from cold storage * @param id The item ID * @returns The item or null if not found */ private getFromColdStorage; /** * Add an item to hot cache * @param id The item ID * @param item The item to cache */ private addToHotCache; /** * Add an item to warm cache * @param id The item ID * @param item The item to cache */ private addToWarmCache; /** * Evict items from hot cache based on LRU policy */ private evictFromHotCache; /** * Set an item in all cache levels * @param id The item ID * @param item The item to cache */ set(id: string, item: T): Promise; /** * Delete an item from all cache levels * @param id The item ID to delete */ delete(id: string): Promise; /** * Clear all cache levels */ clear(): Promise; /** * Get cache statistics * @returns Cache statistics */ getStats(): CacheStats; /** * Prefetch items based on ID patterns or relationships * @param ids Array of IDs to prefetch */ prefetch(ids: string[]): Promise; /** * Check if it's time to tune parameters and do so if needed * This is called before operations that might benefit from tuned parameters * * This method serves as a checkpoint for auto-tuning, ensuring that: * 1. Parameters are tuned periodically based on the auto-tune interval * 2. Tuning happens before critical operations that would benefit from optimized parameters * 3. Tuning doesn't happen too frequently, which could impact performance * * By calling this method before get(), getMany(), and prefetch() operations, * we ensure that the cache parameters are optimized for the current workload * without adding unnecessary overhead to every operation. */ private checkAndTuneParameters; /** * Get multiple items at once, optimizing for batch retrieval * @param ids Array of IDs to get * @returns Map of ID to item */ getMany(ids: string[]): Promise>; /** * Set the storage adapters for warm and cold caches * @param warmStorage Warm cache storage adapter * @param coldStorage Cold storage adapter */ setStorageAdapters(warmStorage: any, coldStorage: any): void; } export {};