use std::collections::HashSet;
use trusty_common::memory_core::store::Triple;
use uuid::Uuid;
use super::apply::{fail, PalaceSink, PalaceView, StoreCounts};
use super::mapping::{drawer_subject, ORIGIN_TAG};
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Retraction {
pub memory_id: String,
pub family: &'static str,
}
fn edge_family(t: &Triple) -> Option<&'static str> {
if t.provenance.as_deref() != Some(ORIGIN_TAG) {
return None;
}
match t.predicate.as_str() {
"mentions" => Some("mentions"),
p if p == "relates_to" || p.starts_with("relates_to:") => Some("relates_to"),
_ => None,
}
}
pub async fn retract_stale(
scope: &[(String, Uuid)],
keep: &HashSet<(String, String, String)>,
view: &dyn PalaceView,
sink: Option<&dyn PalaceSink>,
c: &mut StoreCounts,
) {
for (memory_id, id) in scope {
let active = match view.active_triples(&drawer_subject(*id)).await {
Ok(a) => a,
Err(e) => {
fail(c, "read triples", &e);
continue;
}
};
for t in active {
let Some(family) = edge_family(&t) else {
continue;
};
if keep.contains(&(t.subject.clone(), t.predicate.clone(), t.object.clone())) {
continue;
}
if let Some(s) = sink {
if let Err(e) = s.retract_triple(&t).await {
fail(c, "retract triple", &e);
continue;
}
}
tracing::info!(%memory_id, family, "kuzu import: retracted an edge the source no longer has");
c.retracted.push(Retraction {
memory_id: memory_id.clone(),
family,
});
}
}
}