From c2de14dcab0fe9ac55745cb651772d6ade383a39 Mon Sep 17 00:00:00 2001 From: Kent Overstreet Date: Mon, 13 Apr 2026 21:24:49 -0400 Subject: [PATCH] store: add reindex_relations for after Vec mutations - Add index::clear_relations() to drop and recreate RELS table - Add Store::reindex_relations() to rebuild index from Vec - Call reindex_relations() at end of dedup command This ensures index stays in sync with Vec after complex mutations like UUID redirection in dedup. Vec mutations remain for now but index is correctly updated afterward. Co-Authored-By: Kent Overstreet --- src/cli/admin.rs | 5 +++-- src/hippocampus/store/index.rs | 12 ++++++++++++ src/hippocampus/store/mod.rs | 12 ++++++++++++ 3 files changed, 27 insertions(+), 2 deletions(-) diff --git a/src/cli/admin.rs b/src/cli/admin.rs index de3c987..a9cca43 100644 --- a/src/cli/admin.rs +++ b/src/cli/admin.rs @@ -61,7 +61,7 @@ pub async fn cmd_fsck() -> Result<()> { store::fsck()?; let arc = memory::access_local()?; - let mut store = arc.lock().await; + let store = arc.lock().await; // Check node-key consistency let mut issues = 0; @@ -287,8 +287,9 @@ pub async fn cmd_dedup(apply: bool) -> Result<()> { merged += doomed_uuids.len(); } - // Remove tombstoned relations from cache + // Remove tombstoned relations from cache and rebuild index store.relations.retain(|r| !r.deleted); + store.reindex_relations()?; store.save()?; println!("Merged {} duplicates, redirected {} edges, deduped {} duplicate edges", diff --git a/src/hippocampus/store/index.rs b/src/hippocampus/store/index.rs index 43bbb4f..6615f72 100644 --- a/src/hippocampus/store/index.rs +++ b/src/hippocampus/store/index.rs @@ -209,6 +209,18 @@ pub fn remove_relation( Ok(()) } +/// Clear all relations from the index. +pub fn clear_relations(db: &Database) -> Result<()> { + let txn = db.begin_write()?; + { + // Drop and recreate the table + txn.delete_multimap_table(RELS)?; + let _ = txn.open_multimap_table(RELS)?; + } + txn.commit()?; + Ok(()) +} + /// Get all edges for a node. Returns (other_uuid, strength, rel_type, is_outgoing). pub fn edges_for_node(db: &Database, node_uuid: &[u8; 16]) -> Result> { let txn = db.begin_read()?; diff --git a/src/hippocampus/store/mod.rs b/src/hippocampus/store/mod.rs index c9d57e5..eef031a 100644 --- a/src/hippocampus/store/mod.rs +++ b/src/hippocampus/store/mod.rs @@ -130,6 +130,18 @@ impl Store { Ok(()) } + /// Rebuild relation index from Vec. Call after mutations that modify relations. + pub fn reindex_relations(&self) -> Result<()> { + if let Some(db) = self.db.as_ref() { + index::clear_relations(db)?; + for rel in &self.relations { + if rel.deleted { continue; } + index::index_relation(db, &rel.source, &rel.target, rel.strength, rel.rel_type as u8)?; + } + } + Ok(()) + } + pub fn resolve_key(&self, target: &str) -> Result { // Strip .md suffix if present — keys no longer use it let bare = strip_md_suffix(target);