use crate::active_query::CompletedQuery;
use crate::function::memo::Memo;
use crate::function::{Configuration, IngredientImpl};
use crate::hash::FxIndexSet;
use crate::zalsa::Zalsa;
use crate::zalsa_local::{QueryOriginRef, QueryRevisions, output_edges};
use crate::{DatabaseKeyIndex, Event, EventKind};
impl<C> IngredientImpl<C>
where
C: Configuration,
{
pub(super) fn diff_outputs(
&self,
zalsa: &Zalsa,
key: DatabaseKeyIndex,
old_memo: &Memo<'_, C>,
completed_query: &CompletedQuery,
) {
diff_outputs_on_revision(zalsa, key, &old_memo.revisions, completed_query);
}
}
fn diff_outputs_on_revision(
zalsa: &Zalsa,
key: DatabaseKeyIndex,
old_revisions: &QueryRevisions,
completed_query: &CompletedQuery,
) {
let (QueryOriginRef::Derived(edges) | QueryOriginRef::DerivedUntracked(edges)) =
old_revisions.origin.as_ref()
else {
return;
};
for (identity, id) in &completed_query.stale_tracked_structs {
let output = DatabaseKeyIndex::new(identity.ingredient_index(), *id);
report_stale_output(zalsa, key, output);
}
let mut stale_outputs = output_edges(edges).collect::<FxIndexSet<_>>();
if stale_outputs.is_empty() {
return;
}
for new_output in completed_query.revisions.origin.as_ref().outputs() {
stale_outputs.swap_remove(&new_output);
}
for output in stale_outputs {
report_stale_output(zalsa, key, output);
}
}
fn report_stale_output(zalsa: &Zalsa, key: DatabaseKeyIndex, output: DatabaseKeyIndex) {
zalsa.event(&|| {
Event::new(EventKind::WillDiscardStaleOutput {
execute_key: key,
output_key: output,
})
});
output.remove_stale_output(zalsa, key);
}