store: convert more callers to use RELS index
Convert remaining Vec users to index-based access: - memory.rs: MemoryNode::from_store uses Store::neighbors() - graph.rs: orphan detection uses for_each_relation - local.rs: normalize_strengths uses for_each_relation + set_link_strength Add Store::neighbors() method and index::get_offsets_for_uuid(). Cleanup: - for_each_relation: build both uuid↔key maps in one pass - cap_degree: consolidate key/uuid/degree collection Remaining Vec uses: admin.rs (fsck, dedup), capnp.rs (load path). Co-Authored-By: Kent Overstreet <kent.overstreet@linux.dev>
This commit is contained in:
parent
5fe51fbfda
commit
5832e57970
8 changed files with 109 additions and 81 deletions
|
|
@ -397,43 +397,46 @@ pub fn graph_communities(store: &Store, _provenance: &str, top_n: Option<usize>,
|
|||
}
|
||||
|
||||
pub fn graph_normalize_strengths(store: &mut Store, _provenance: &str, apply: Option<bool>) -> Result<String> {
|
||||
use crate::store::{StoreView, RelationType};
|
||||
|
||||
let apply = apply.unwrap_or(false);
|
||||
let graph = store.build_graph();
|
||||
let strengths = graph.jaccard_strengths();
|
||||
|
||||
// Build lookup from (source_key, target_key) → new_strength
|
||||
let mut updates: std::collections::HashMap<(String, String), f32> = std::collections::HashMap::new();
|
||||
let mut target_strengths: std::collections::HashMap<(String, String), f32> = std::collections::HashMap::new();
|
||||
for (a, b, s) in &strengths {
|
||||
updates.insert((a.clone(), b.clone()), *s);
|
||||
updates.insert((b.clone(), a.clone()), *s);
|
||||
target_strengths.insert((a.clone(), b.clone()), *s);
|
||||
target_strengths.insert((b.clone(), a.clone()), *s);
|
||||
}
|
||||
|
||||
let mut changed = 0usize;
|
||||
// Collect edges and compute changes
|
||||
let mut to_update: Vec<(String, String, f32)> = Vec::new();
|
||||
let mut unchanged = 0usize;
|
||||
let mut temporal_skipped = 0usize;
|
||||
let mut delta_sum: f64 = 0.0;
|
||||
let mut buckets = [0usize; 10];
|
||||
|
||||
for rel in &mut store.relations {
|
||||
if rel.deleted { continue; }
|
||||
if rel.strength == 1.0 && rel.rel_type == crate::store::RelationType::Auto {
|
||||
store.for_each_relation(|source, target, strength, rel_type| {
|
||||
// Skip temporal links
|
||||
if strength == 1.0 && rel_type == RelationType::Auto {
|
||||
temporal_skipped += 1;
|
||||
continue;
|
||||
return;
|
||||
}
|
||||
if let Some(&new_s) = updates.get(&(rel.source_key.clone(), rel.target_key.clone())) {
|
||||
let old_s = rel.strength;
|
||||
let delta = (new_s - old_s).abs();
|
||||
if let Some(&new_s) = target_strengths.get(&(source.to_string(), target.to_string())) {
|
||||
let delta = (new_s - strength).abs();
|
||||
if delta > 0.001 {
|
||||
delta_sum += delta as f64;
|
||||
if apply { rel.strength = new_s; }
|
||||
changed += 1;
|
||||
to_update.push((source.to_string(), target.to_string(), new_s));
|
||||
} else {
|
||||
unchanged += 1;
|
||||
}
|
||||
let bucket = ((new_s * 10.0) as usize).min(9);
|
||||
buckets[bucket] += 1;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
let changed = to_update.len();
|
||||
|
||||
use std::fmt::Write;
|
||||
let mut out = String::new();
|
||||
|
|
@ -455,7 +458,9 @@ pub fn graph_normalize_strengths(store: &mut Store, _provenance: &str, apply: Op
|
|||
}
|
||||
|
||||
if apply {
|
||||
store.save().map_err(|e| anyhow::anyhow!("{}", e))?;
|
||||
for (source, target, new_strength) in to_update {
|
||||
store.set_link_strength(&source, &target, new_strength)?;
|
||||
}
|
||||
writeln!(out, "\nApplied {} strength updates.", changed).ok();
|
||||
} else {
|
||||
writeln!(out, "\nDry run. Pass apply:true to write changes.").ok();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue