capnp_store: remove dead code, consolidate CRUD API

Dead code removed:
- rebuild_uuid_index (never called, index built during load)
- node_weight inherent method (all callers use StoreView trait)
- node_community (no callers)
- state_json_path (no callers)
- log_retrieval, log_retrieval_append (no callers; only _static is used)
- memory_dir_pub wrapper (just make memory_dir pub directly)

API consolidation:
- insert_node eliminated — callers use upsert_node (same behavior
  for new nodes, plus handles re-upsert gracefully)

AnyView StoreView dispatch compressed to one line per method
(also removes UFCS workaround that was needed when inherent
node_weight shadowed the trait method).

-69 lines net.
This commit is contained in:
ProofOfConcept 2026-03-03 12:38:52 -05:00
parent 0bce6aac3c
commit 70a5f05ce0
3 changed files with 11 additions and 80 deletions

View file

@ -101,17 +101,14 @@ macro_rules! capnp_message {
}
// Data dir: ~/.claude/memory/
fn memory_dir() -> PathBuf {
pub fn memory_dir() -> PathBuf {
PathBuf::from(env::var("HOME").expect("HOME not set"))
.join(".claude/memory")
}
pub fn memory_dir_pub() -> PathBuf { memory_dir() }
fn nodes_path() -> PathBuf { memory_dir().join("nodes.capnp") }
fn relations_path() -> PathBuf { memory_dir().join("relations.capnp") }
fn state_path() -> PathBuf { memory_dir().join("state.bin") }
fn state_json_path() -> PathBuf { memory_dir().join("state.json") }
fn lock_path() -> PathBuf { memory_dir().join(".store.lock") }
/// RAII file lock using flock(2). Dropped when scope exits.
@ -600,45 +597,22 @@ impl AnyView {
impl StoreView for AnyView {
fn for_each_node<F: FnMut(&str, &str, f32)>(&self, f: F) {
match self {
AnyView::Mmap(v) => v.for_each_node(f),
AnyView::Owned(s) => s.for_each_node(f),
match self { AnyView::Mmap(v) => v.for_each_node(f), AnyView::Owned(s) => s.for_each_node(f) }
}
}
fn for_each_relation<F: FnMut(&str, &str, f32, RelationType)>(&self, f: F) {
match self {
AnyView::Mmap(v) => v.for_each_relation(f),
AnyView::Owned(s) => s.for_each_relation(f),
match self { AnyView::Mmap(v) => v.for_each_relation(f), AnyView::Owned(s) => s.for_each_relation(f) }
}
}
fn node_weight(&self, key: &str) -> f64 {
match self {
AnyView::Mmap(v) => v.node_weight(key),
AnyView::Owned(s) => StoreView::node_weight(s, key),
match self { AnyView::Mmap(v) => v.node_weight(key), AnyView::Owned(s) => s.node_weight(key) }
}
}
fn node_content(&self, key: &str) -> Option<&str> {
match self {
AnyView::Mmap(v) => v.node_content(key),
AnyView::Owned(s) => s.node_content(key),
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),
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(),
}
match self { AnyView::Mmap(v) => v.params(), AnyView::Owned(s) => s.params() }
}
}
@ -995,14 +969,6 @@ impl Store {
Ok(())
}
/// Insert a fully constructed node (for journal entries, imports, etc.)
pub fn insert_node(&mut self, node: Node) -> Result<(), String> {
self.append_nodes(std::slice::from_ref(&node))?;
self.uuid_to_key.insert(node.uuid, node.key.clone());
self.nodes.insert(node.key.clone(), node);
Ok(())
}
/// Create a new node with defaults
pub fn new_node(key: &str, content: &str) -> Node {
Node {
@ -1131,25 +1097,10 @@ impl Store {
Ok(count)
}
fn rebuild_uuid_index(&mut self) {
self.uuid_to_key.clear();
for (key, node) in &self.nodes {
self.uuid_to_key.insert(node.uuid, key.clone());
}
}
pub fn build_graph(&self) -> Graph {
graph::build_graph(self)
}
pub fn node_weight(&self, key: &str) -> Option<f32> {
self.nodes.get(key).map(|n| n.weight)
}
pub fn node_community(&self, key: &str) -> Option<u32> {
self.nodes.get(key).and_then(|n| n.community_id)
}
pub fn resolve_key(&self, target: &str) -> Result<String, String> {
let normalized = if target.contains('#') {
let parts: Vec<&str> = target.splitn(2, '#').collect();
@ -1228,26 +1179,6 @@ impl Store {
Some((redirected, n.uuid))
}
pub fn log_retrieval(&mut self, query: &str, results: &[String]) {
self.retrieval_log.push(RetrievalEvent {
query: query.to_string(),
timestamp: today(),
results: results.to_vec(),
used: None,
});
// Keep last 100
if self.retrieval_log.len() > 100 {
let start = self.retrieval_log.len() - 100;
self.retrieval_log = self.retrieval_log[start..].to_vec();
}
}
/// Lightweight retrieval logging — appends one line to retrieval.log
/// instead of rewriting the entire state.bin.
pub fn log_retrieval_append(&self, query: &str, results: &[String]) {
Self::log_retrieval_static(query, results);
}
/// Append retrieval event to retrieval.log without needing a Store instance.
pub fn log_retrieval_static(query: &str, results: &[String]) {
let path = memory_dir().join("retrieval.log");

View file

@ -19,7 +19,7 @@ use std::path::{Path, PathBuf};
use std::process::Command;
fn memory_dir() -> PathBuf {
capnp_store::memory_dir_pub()
capnp_store::memory_dir()
}
fn episodic_dir() -> PathBuf {

View file

@ -1357,7 +1357,7 @@ fn cmd_import(args: &[String]) -> Result<(), String> {
let resolved = if path.exists() {
path
} else {
let mem_path = capnp_store::memory_dir_pub().join(arg);
let mem_path = capnp_store::memory_dir().join(arg);
if !mem_path.exists() {
eprintln!("File not found: {}", arg);
continue;
@ -1401,7 +1401,7 @@ fn cmd_export(args: &[String]) -> Result<(), String> {
}).collect()
};
let mem_dir = capnp_store::memory_dir_pub();
let mem_dir = capnp_store::memory_dir();
for file_key in &targets {
match store.export_to_markdown(file_key) {
@ -1455,7 +1455,7 @@ fn cmd_journal_write(args: &[String]) -> Result<(), String> {
node.source_ref = src;
}
store.insert_node(node)?;
store.upsert_node(node)?;
store.save()?;
let word_count = text.split_whitespace().count();