From a2ec8657d2453fed13a588197b857adbb4491781 Mon Sep 17 00:00:00 2001 From: ProofOfConcept Date: Tue, 3 Mar 2026 12:42:16 -0500 Subject: [PATCH] capnp_store: remove dead has_node trait method, fix fix_categories bulk write - has_node: defined on StoreView trait but never called externally - fix_categories: was appending ALL nodes when only changed ones needed persisting; now collects changed nodes and appends only those - save_snapshot: pass log sizes from caller instead of re-statting files - params: use Copy instead of .clone() in snapshot construction --- src/capnp_store.rs | 36 +++++++++--------------------------- 1 file changed, 9 insertions(+), 27 deletions(-) diff --git a/src/capnp_store.rs b/src/capnp_store.rs index 536d7ed..443862b 100644 --- a/src/capnp_store.rs +++ b/src/capnp_store.rs @@ -440,9 +440,6 @@ pub trait StoreView { /// Node content by key. fn node_content(&self, key: &str) -> Option<&str>; - /// Check if a node exists. - fn has_node(&self, key: &str) -> bool; - /// Search/graph parameters. fn params(&self) -> Params; } @@ -469,10 +466,6 @@ impl StoreView for Store { self.nodes.get(key).map(|n| n.content.as_str()) } - fn has_node(&self, key: &str) -> bool { - self.nodes.contains_key(key) - } - fn params(&self) -> Params { self.params } @@ -554,10 +547,6 @@ impl StoreView for MmapView { snap.nodes.get(key).map(|n| &*n.content) } - fn has_node(&self, key: &str) -> bool { - self.snapshot().nodes.get(key).is_some() - } - fn params(&self) -> Params { let p = &self.snapshot().params; Params { @@ -608,9 +597,6 @@ impl StoreView for AnyView { fn node_content(&self, key: &str) -> Option<&str> { match self { AnyView::Mmap(v) => v.node_content(key), AnyView::Owned(s) => s.node_content(key) } } - fn has_node(&self, key: &str) -> bool { - match self { AnyView::Mmap(v) => v.has_node(key), AnyView::Owned(s) => s.has_node(key) } - } fn params(&self) -> Params { match self { AnyView::Mmap(v) => v.params(), AnyView::Owned(s) => s.params() } } @@ -652,7 +638,7 @@ impl Store { } // Bootstrap: write rkyv snapshot if missing if !snapshot_path().exists() { - if let Err(e) = store.save_snapshot_inner() { + if let Err(e) = store.save_snapshot(cached_nodes, cached_rels) { eprintln!("rkyv bootstrap: {}", e); } } @@ -819,7 +805,7 @@ impl Store { .map_err(|e| format!("rename {} → {}: {}", tmp_path.display(), path.display(), e))?; // Also write rkyv snapshot (mmap-friendly) - if let Err(e) = self.save_snapshot_inner() { + if let Err(e) = self.save_snapshot(nodes_size, rels_size) { eprintln!("rkyv snapshot save: {}", e); } @@ -828,20 +814,17 @@ impl Store { /// Serialize store as rkyv snapshot with staleness header. /// Assumes StoreLock is already held by caller. - fn save_snapshot_inner(&self) -> Result<(), String> { + fn save_snapshot(&self, nodes_size: u64, rels_size: u64) -> Result<(), String> { let snap = Snapshot { nodes: self.nodes.clone(), relations: self.relations.iter().filter(|r| !r.deleted).cloned().collect(), gaps: self.gaps.clone(), - params: self.params.clone(), + params: self.params, }; let rkyv_data = rkyv::to_bytes::<_, 256>(&snap) .map_err(|e| format!("rkyv serialize: {}", e))?; - let nodes_size = fs::metadata(nodes_path()).map(|m| m.len()).unwrap_or(0); - let rels_size = fs::metadata(relations_path()).map(|m| m.len()).unwrap_or(0); - let mut data = Vec::with_capacity(RKYV_HEADER_LEN + rkyv_data.len()); data.extend_from_slice(&RKYV_MAGIC); data.extend_from_slice(&1u32.to_le_bytes()); // format version @@ -1288,7 +1271,7 @@ impl Store { ]; let obs_prefixes = ["skill-", "worked-example-"]; - let mut changed = 0; + let mut changed_nodes = Vec::new(); let mut unchanged = 0; let keys: Vec = self.nodes.keys().cloned().collect(); @@ -1321,18 +1304,17 @@ impl Store { let node = self.nodes.get_mut(key).unwrap(); node.category = cat; node.version += 1; - changed += 1; + changed_nodes.push(node.clone()); } else { unchanged += 1; } } - if changed > 0 { - let updated: Vec = self.nodes.values().cloned().collect(); - self.append_nodes(&updated)?; + if !changed_nodes.is_empty() { + self.append_nodes(&changed_nodes)?; } - Ok((changed, unchanged)) + Ok((changed_nodes.len(), unchanged)) } /// Cap node degree by soft-deleting edges from mega-hubs.