fix(memory-vector): seed JVector index from SQLite on VectorMemorySystem.open()
После рестарта in-RAM граф JVector создавался пустым (seedEntries не проходились из metaStore), поэтому search возвращал [], пока не появлялись новые upsert'ы — память терялась после каждого рестарта. - VectorMemorySystem.open(): JVectorMemoryIndex(dimension, metaStore.allEntries()) - SqliteMemoryMetaStore.open(): убрал случайное двойное конструирование - регресс-тест openSeedsIndexFromSqliteAfterRestart (save → close → open → search)
This commit is contained in:
-1
@@ -194,7 +194,6 @@ class SqliteMemoryMetaStore(
|
|||||||
*/
|
*/
|
||||||
fun open(dbPath: String, dimension: Int): SqliteMemoryMetaStore {
|
fun open(dbPath: String, dimension: Int): SqliteMemoryMetaStore {
|
||||||
val conn = DriverManager.getConnection("jdbc:sqlite:$dbPath")
|
val conn = DriverManager.getConnection("jdbc:sqlite:$dbPath")
|
||||||
SqliteMemoryMetaStore(conn, dimension)
|
|
||||||
return SqliteMemoryMetaStore(conn, dimension)
|
return SqliteMemoryMetaStore(conn, dimension)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-1
@@ -45,7 +45,10 @@ class VectorMemorySystem(
|
|||||||
topK: Int = 10,
|
topK: Int = 10,
|
||||||
): VectorMemorySystem {
|
): VectorMemorySystem {
|
||||||
val metaStore = SqliteMemoryMetaStore.open(dbPath, embedding.dimension)
|
val metaStore = SqliteMemoryMetaStore.open(dbPath, embedding.dimension)
|
||||||
val index = JVectorMemoryIndex(embedding.dimension)
|
// Граф пересобирается из SQLite (источник правды): без seed'ов
|
||||||
|
// после рестарта in-RAM индекс пуст и search возвращал бы [],
|
||||||
|
// пока не появятся новые upsert'ы.
|
||||||
|
val index = JVectorMemoryIndex(embedding.dimension, metaStore.allEntries())
|
||||||
val store = VectorMemoryStore(index, metaStore, embedding)
|
val store = VectorMemoryStore(index, metaStore, embedding)
|
||||||
val prefetcher = VectorPrefetcher(store, topK)
|
val prefetcher = VectorPrefetcher(store, topK)
|
||||||
val reviewer = VectorMemoryReviewer(store)
|
val reviewer = VectorMemoryReviewer(store)
|
||||||
|
|||||||
+17
@@ -136,4 +136,21 @@ class VectorMemoryStoreTest {
|
|||||||
store2.close()
|
store2.close()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun openSeedsIndexFromSqliteAfterRestart() = runTest {
|
||||||
|
// Регрессия: VectorMemorySystem.open() обязан пересадить in-RAM граф
|
||||||
|
// из SQLite — иначе после рестарта search возвращает [] до первого upsert.
|
||||||
|
val first = VectorMemorySystem.open(file.absolutePath, FakeEmbeddingProvider(dimension = dim))
|
||||||
|
first.store.upsert(makeNote("r", "restarted fact: dog rex poodle"))
|
||||||
|
first.close()
|
||||||
|
|
||||||
|
val second = VectorMemorySystem.open(file.absolutePath, FakeEmbeddingProvider(dimension = dim))
|
||||||
|
try {
|
||||||
|
val results = second.store.search(MemorySearchQuery(query = "restarted fact", topK = 5))
|
||||||
|
assertTrue(results.any { it.note.id == "r" })
|
||||||
|
} finally {
|
||||||
|
second.close()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user