Open source vector database with HNSW indexing, graph relationships, and metadata facets. Features CLI with professional augmentation registry integration for discovering extensions and capabilities.
331 lines
11 KiB
TypeScript
331 lines
11 KiB
TypeScript
/**
|
|
* 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<any>;
|
|
[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<T extends HNSWNode | Edge | HNSWVerb> {
|
|
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<T | null>;
|
|
/**
|
|
* 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<void>;
|
|
/**
|
|
* Delete an item from all cache levels
|
|
* @param id The item ID to delete
|
|
*/
|
|
delete(id: string): Promise<void>;
|
|
/**
|
|
* Clear all cache levels
|
|
*/
|
|
clear(): Promise<void>;
|
|
/**
|
|
* 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<void>;
|
|
/**
|
|
* 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<Map<string, T>>;
|
|
/**
|
|
* 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 {};
|