| 87 | * Uses an in-memory Map with periodic flush to a compact binary file. |
| 88 | */ |
| 89 | export class RvfEmbeddingCache { |
| 90 | private readonly cachePath: string; |
| 91 | private readonly maxSize: number; |
| 92 | private readonly ttlMs: number; |
| 93 | private readonly dimensions: number | undefined; |
| 94 | |
| 95 | private entries: Map<number, CacheEntry> = new Map(); |
| 96 | private textToHash: Map<string, number> = new Map(); |
| 97 | private dirty = false; |
| 98 | private flushTimer: ReturnType<typeof setInterval> | null = null; |
| 99 | private initialized = false; |
| 100 | |
| 101 | constructor(config: RvfEmbeddingCacheConfig) { |
| 102 | this.cachePath = config.cachePath; |
| 103 | this.maxSize = config.maxSize ?? DEFAULT_MAX_SIZE; |
| 104 | this.ttlMs = config.ttlMs ?? DEFAULT_TTL_MS; |
| 105 | this.dimensions = config.dimensions; |
| 106 | validatePath(this.cachePath); |
| 107 | } |
| 108 | |
| 109 | // -------------------------------------------------------------------------- |
| 110 | // Initialization |
| 111 | // -------------------------------------------------------------------------- |
| 112 | |
| 113 | /** |
| 114 | * Lazily initialize the cache: load from disk if file exists, start auto-flush. |
| 115 | */ |
| 116 | private async ensureInitialized(): Promise<void> { |
| 117 | if (this.initialized) return; |
| 118 | |
| 119 | // Ensure parent directory exists |
| 120 | const dir = dirname(this.cachePath); |
| 121 | if (!existsSync(dir)) { |
| 122 | mkdirSync(dir, { recursive: true }); |
| 123 | } |
| 124 | |
| 125 | // Load existing cache file |
| 126 | if (existsSync(this.cachePath)) { |
| 127 | this.loadFromFile(); |
| 128 | } |
| 129 | |
| 130 | // Clean expired entries on startup |
| 131 | this.cleanExpired(); |
| 132 | |
| 133 | // Start auto-flush timer |
| 134 | this.startAutoFlush(); |
| 135 | |
| 136 | this.initialized = true; |
| 137 | } |
| 138 | |
| 139 | // -------------------------------------------------------------------------- |
| 140 | // Public API (matches PersistentEmbeddingCache) |
| 141 | // -------------------------------------------------------------------------- |
| 142 | |
| 143 | /** |
| 144 | * Get an embedding from the cache by text. |
| 145 | * Returns null if not found or expired. |
| 146 | */ |
nothing calls this directly
no outgoing calls
no test coverage detected