Skip to content

Commit c52ab2b

Browse files
authored
fix(embedder): update LRU insertion order when re-setting existing key (CortexReach#658)
Issue CortexReach#598 Phase 3: When an existing cache key is re-set, explicitly delete it first to maintain correct LRU ordering. Without this, the insertion order stays stale and the LRU eviction removes the wrong entry. Also adds unit test for LRU semantics.
1 parent a8bb8ec commit c52ab2b

2 files changed

Lines changed: 36 additions & 0 deletions

File tree

src/embedder.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,10 @@ class EmbeddingCache {
6969

7070
set(text: string, task: string | undefined, vector: number[]): void {
7171
const k = this.key(text, task);
72+
// If key already exists, delete to update insertion order for correct LRU semantics
73+
if (this.cache.has(k)) {
74+
this.cache.delete(k);
75+
}
7276
// When cache is full, run TTL eviction first (removes expired + oldest).
7377
// This prevents unbounded growth from stale entries while keeping writes O(1).
7478
if (this.cache.size >= this.maxSize) {

test/embedder-lru.test.mjs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/**
2+
* Issue #598 Phase 3 - EmbeddingCache LRU Semantics Test
3+
* Tests that re-setting an existing key updates its LRU position.
4+
*/
5+
6+
import { describe, it } from "node:test";
7+
import assert from "node:assert";
8+
9+
const jiti = require("jiti")(__filename);
10+
11+
describe("EmbeddingCache LRU semantics", () => {
12+
it("updates insertion order when re-setting existing key", async () => {
13+
const { Embedder } = jiti("../src/embedder.ts");
14+
15+
const embedder = new Embedder({});
16+
const cache = embedder["cache"];
17+
18+
// Set two keys
19+
cache.set("key1", undefined, [1, 0, 0]);
20+
cache.set("key2", undefined, [0, 1, 0]);
21+
22+
// Re-set key1 with different value (should move to most recent)
23+
cache.set("key1", undefined, [1, 1, 0]);
24+
25+
// Evict one - should evict key2 (oldest), not key1 (which was re-set)
26+
cache.set("key3", undefined, [0, 0, 1]);
27+
28+
assert.strictEqual(cache.cache.has("key1"), true, "key1 should remain after re-set");
29+
assert.strictEqual(cache.cache.has("key2"), false, "key2 should be evicted (oldest)");
30+
assert.strictEqual(cache.cache.has("key3"), true, "key3 should be added");
31+
});
32+
});

0 commit comments

Comments
 (0)