perf(sqlite): use existence probes for empty memory search

This commit is contained in:
Vincent Koc
2026-03-24 13:12:14 -07:00
parent f6a0cdc25a
commit 7d6d112656
2 changed files with 33 additions and 19 deletions

View File

@@ -216,6 +216,7 @@ describe("memory index", () => {
vectorEnabled?: boolean;
cacheEnabled?: boolean;
minScore?: number;
onSearch?: boolean;
hybrid?: { enabled: boolean; vectorWeight?: number; textWeight?: number };
}): TestCfg {
return {
@@ -229,7 +230,7 @@ describe("memory index", () => {
store: { path: params.storePath, vector: { enabled: params.vectorEnabled ?? false } },
// Perf: keep test indexes to a single chunk to reduce sqlite work.
chunking: { tokens: 4000, overlap: 0 },
sync: { watch: false, onSessionStart: false, onSearch: true },
sync: { watch: false, onSessionStart: false, onSearch: params.onSearch ?? true },
query: {
minScore: params.minScore ?? 0,
hybrid: params.hybrid ?? { enabled: false },
@@ -970,6 +971,25 @@ describe("memory index", () => {
await manager.close?.();
});
it("does not initialize the provider when searching an empty index", async () => {
const cfg = createCfg({
storePath: path.join(workspaceDir, `index-empty-${randomUUID()}.sqlite`),
provider: "gemini",
model: "gemini-embedding-2-preview",
outputDimensionality: 1536,
onSearch: false,
});
const result = await getMemorySearchManager({ cfg, agentId: "main" });
const manager = requireManager(result);
const results = await manager.search("hello");
expect(results).toEqual([]);
expect(providerCalls).toEqual([]);
await manager.close?.();
});
it("reindexes when Gemini outputDimensionality changes", async () => {
const base = createCfg({
storePath: indexModelPath,

View File

@@ -436,29 +436,23 @@ export class MemoryIndexManager extends MemoryManagerEmbeddingOps implements Mem
}
private hasIndexedContent(): boolean {
const chunks =
(
this.db.prepare(`SELECT COUNT(*) as c FROM chunks`).get() as
| {
c: number;
}
| undefined
)?.c ?? 0;
if (chunks > 0) {
const chunkRow = this.db.prepare(`SELECT 1 as found FROM chunks LIMIT 1`).get() as
| {
found?: number;
}
| undefined;
if (chunkRow?.found === 1) {
return true;
}
if (!this.fts.enabled || !this.fts.available) {
return false;
}
const ftsRows =
(
this.db.prepare(`SELECT COUNT(*) as c FROM ${FTS_TABLE}`).get() as
| {
c: number;
}
| undefined
)?.c ?? 0;
return ftsRows > 0;
const ftsRow = this.db.prepare(`SELECT 1 as found FROM ${FTS_TABLE} LIMIT 1`).get() as
| {
found?: number;
}
| undefined;
return ftsRow?.found === 1;
}
private async searchVector(