forked from kent/consciousness
store: remove nodes and uuid_to_key HashMaps
All node access now goes through index → capnp: - scoring.rs: consolidation_priority, replay_queue, consolidation_plan - admin.rs: cmd_init, cmd_fsck, cmd_dedup - engine.rs: run_generator, eval_filter, run_transform - parser.rs: resolve_field, execute_query Added Store::remove_from_index() for dedup cleanup. The relations Vec remains for now (used for graph building). Co-Authored-By: Proof of Concept <poc@bcachefs.org>
This commit is contained in:
parent
af3e41f1d9
commit
5877fd857a
5 changed files with 65 additions and 47 deletions
|
|
@ -227,10 +227,10 @@ fn score_field(
|
|||
(d / max).min(1.0)
|
||||
}
|
||||
ScoreField::Weight => {
|
||||
store.nodes.get(key).map(|n| n.weight as f64).unwrap_or(0.0)
|
||||
store.get_node(key).ok().flatten().map(|n| n.weight as f64).unwrap_or(0.0)
|
||||
}
|
||||
ScoreField::ContentLen => {
|
||||
let len = store.nodes.get(key).map(|n| n.content.len()).unwrap_or(0) as f64;
|
||||
let len = store.get_node(key).ok().flatten().map(|n| n.content.len()).unwrap_or(0) as f64;
|
||||
let max = precomputed.max_content_len.max(1.0);
|
||||
(len / max).min(1.0)
|
||||
}
|
||||
|
|
@ -255,7 +255,7 @@ impl CompositeCache {
|
|||
.map(|(k, _)| graph.degree(k) as f64)
|
||||
.fold(0.0f64, f64::max);
|
||||
let max_content_len = items.iter()
|
||||
.map(|(k, _)| store.nodes.get(k).map(|n| n.content.len()).unwrap_or(0) as f64)
|
||||
.map(|(k, _)| store.get_node(k).ok().flatten().map(|n| n.content.len()).unwrap_or(0) as f64)
|
||||
.fold(0.0f64, f64::max);
|
||||
Self {
|
||||
isolation: graph.community_isolation(),
|
||||
|
|
@ -393,9 +393,12 @@ pub fn run_query(
|
|||
fn run_generator(g: &Generator, store: &Store) -> Vec<(String, f64)> {
|
||||
match g {
|
||||
Generator::All => {
|
||||
store.nodes.iter()
|
||||
.filter(|(_, n)| !n.deleted)
|
||||
.map(|(key, n)| (key.clone(), n.weight as f64))
|
||||
store.all_keys().unwrap_or_default().into_iter()
|
||||
.filter_map(|key| {
|
||||
let n = store.get_node(&key).ok()??;
|
||||
if n.deleted { return None; }
|
||||
Some((key, n.weight as f64))
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
Generator::Match(terms) => {
|
||||
|
|
@ -409,7 +412,7 @@ fn run_generator(g: &Generator, store: &Store) -> Vec<(String, f64)> {
|
|||
}
|
||||
|
||||
pub fn eval_filter(filt: &Filter, key: &str, store: &Store, now: i64) -> bool {
|
||||
let node = match store.nodes.get(key) {
|
||||
let node = match store.get_node(key).ok().flatten() {
|
||||
Some(n) => n,
|
||||
None => return false,
|
||||
};
|
||||
|
|
@ -442,15 +445,15 @@ pub fn run_transform(
|
|||
}
|
||||
SortField::Timestamp => {
|
||||
items.sort_by(|a, b| {
|
||||
let ta = store.nodes.get(&a.0).map(|n| n.timestamp).unwrap_or(0);
|
||||
let tb = store.nodes.get(&b.0).map(|n| n.timestamp).unwrap_or(0);
|
||||
let ta = store.get_node(&a.0).ok().flatten().map(|n| n.timestamp).unwrap_or(0);
|
||||
let tb = store.get_node(&b.0).ok().flatten().map(|n| n.timestamp).unwrap_or(0);
|
||||
tb.cmp(&ta) // desc
|
||||
});
|
||||
}
|
||||
SortField::ContentLen => {
|
||||
items.sort_by(|a, b| {
|
||||
let la = store.nodes.get(&a.0).map(|n| n.content.len()).unwrap_or(0);
|
||||
let lb = store.nodes.get(&b.0).map(|n| n.content.len()).unwrap_or(0);
|
||||
let la = store.get_node(&a.0).ok().flatten().map(|n| n.content.len()).unwrap_or(0);
|
||||
let lb = store.get_node(&b.0).ok().flatten().map(|n| n.content.len()).unwrap_or(0);
|
||||
lb.cmp(&la) // desc
|
||||
});
|
||||
}
|
||||
|
|
@ -480,7 +483,7 @@ pub fn run_transform(
|
|||
SortField::Named(field, asc) => {
|
||||
// Resolve field from node properties
|
||||
let resolve = |key: &str| -> Option<f64> {
|
||||
let node = store.nodes.get(key)?;
|
||||
let node = store.get_node(key).ok()??;
|
||||
match field.as_str() {
|
||||
"weight" => Some(node.weight as f64),
|
||||
"emotion" => Some(node.emotion as f64),
|
||||
|
|
|
|||
|
|
@ -300,7 +300,7 @@ pub fn parse_stages(s: &str) -> Result<Vec<Stage>, String> {
|
|||
|
||||
/// Resolve a field value from a node + graph context, returning a comparable Value.
|
||||
fn resolve_field(field: &str, key: &str, store: &Store, graph: &Graph) -> Option<Value> {
|
||||
let node = store.nodes.get(key)?;
|
||||
let node = store.get_node(key).ok()??;
|
||||
match field {
|
||||
"key" => Some(Value::Str(key.to_string())),
|
||||
"weight" => Some(Value::Num(node.weight as f64)),
|
||||
|
|
@ -491,9 +491,13 @@ fn execute_parsed(
|
|||
}
|
||||
_ => {
|
||||
let mut out = Vec::new();
|
||||
for key in store.nodes.keys() {
|
||||
if store.nodes[key].deleted { continue; }
|
||||
if eval(&q.expr, &|f| resolve_field(f, key, store, graph), store, graph) {
|
||||
for key in store.all_keys().unwrap_or_default() {
|
||||
let node = match store.get_node(&key).ok().flatten() {
|
||||
Some(n) => n,
|
||||
None => continue,
|
||||
};
|
||||
if node.deleted { continue; }
|
||||
if eval(&q.expr, &|f| resolve_field(f, &key, store, graph), store, graph) {
|
||||
out.push(QueryResult { key: key.clone(), fields: BTreeMap::new() });
|
||||
}
|
||||
}
|
||||
|
|
@ -565,15 +569,15 @@ fn execute_parsed(
|
|||
}
|
||||
SortField::Weight => {
|
||||
results.sort_by(|a, b| {
|
||||
let wa = store.nodes.get(&a.key).map(|n| n.weight).unwrap_or(0.0);
|
||||
let wb = store.nodes.get(&b.key).map(|n| n.weight).unwrap_or(0.0);
|
||||
let wa = store.get_node(&a.key).ok().flatten().map(|n| n.weight).unwrap_or(0.0);
|
||||
let wb = store.get_node(&b.key).ok().flatten().map(|n| n.weight).unwrap_or(0.0);
|
||||
wb.total_cmp(&wa)
|
||||
});
|
||||
}
|
||||
SortField::Timestamp => {
|
||||
results.sort_by(|a, b| {
|
||||
let ta = store.nodes.get(&a.key).map(|n| n.timestamp).unwrap_or(0);
|
||||
let tb = store.nodes.get(&b.key).map(|n| n.timestamp).unwrap_or(0);
|
||||
let ta = store.get_node(&a.key).ok().flatten().map(|n| n.timestamp).unwrap_or(0);
|
||||
let tb = store.get_node(&b.key).ok().flatten().map(|n| n.timestamp).unwrap_or(0);
|
||||
tb.cmp(&ta)
|
||||
});
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue