Make QueryEdge an enum

This commit is contained in:
Lukas Wirth 2025-01-04 15:20:59 +01:00
parent 153bdb42c5
commit fa565f9c26
3 changed files with 20 additions and 46 deletions

View file

@ -78,7 +78,7 @@ impl ActiveQuery {
revision: Revision, revision: Revision,
accumulated: InputAccumulatedValues, accumulated: InputAccumulatedValues,
) { ) {
self.input_outputs.insert(QueryEdge::input(input)); self.input_outputs.insert(QueryEdge::Input(input));
self.durability = self.durability.min(durability); self.durability = self.durability.min(durability);
self.changed_at = self.changed_at.max(revision); self.changed_at = self.changed_at.max(revision);
self.accumulated.add_input(accumulated); self.accumulated.add_input(accumulated);
@ -98,12 +98,12 @@ impl ActiveQuery {
/// Adds a key to our list of outputs. /// Adds a key to our list of outputs.
pub(super) fn add_output(&mut self, key: DependencyIndex) { pub(super) fn add_output(&mut self, key: DependencyIndex) {
self.input_outputs.insert(QueryEdge::output(key)); self.input_outputs.insert(QueryEdge::Output(key));
} }
/// True if the given key was output by this query. /// True if the given key was output by this query.
pub(super) fn is_output(&self, key: DependencyIndex) -> bool { pub(super) fn is_output(&self, key: DependencyIndex) -> bool {
self.input_outputs.contains(&QueryEdge::output(key)) self.input_outputs.contains(&QueryEdge::Output(key))
} }
pub(crate) fn into_revisions(self) -> QueryRevisions { pub(crate) fn into_revisions(self) -> QueryRevisions {
@ -138,7 +138,7 @@ impl ActiveQuery {
pub(super) fn remove_cycle_participants(&mut self, cycle: &Cycle) { pub(super) fn remove_cycle_participants(&mut self, cycle: &Cycle) {
for p in cycle.participant_keys() { for p in cycle.participant_keys() {
let p: DependencyIndex = p.into(); let p: DependencyIndex = p.into();
self.input_outputs.shift_remove(&QueryEdge::input(p)); self.input_outputs.shift_remove(&QueryEdge::Input(p));
} }
} }

View file

@ -1,7 +1,7 @@
use crate::{ use crate::{
key::DatabaseKeyIndex, key::DatabaseKeyIndex,
zalsa::{Zalsa, ZalsaDatabase}, zalsa::{Zalsa, ZalsaDatabase},
zalsa_local::{ActiveQueryGuard, EdgeKind, QueryEdge, QueryOrigin}, zalsa_local::{ActiveQueryGuard, QueryEdge, QueryOrigin},
AsDynDatabase as _, Id, Revision, AsDynDatabase as _, Id, Revision,
}; };
@ -182,20 +182,16 @@ where
// valid, then some later input I1 might never have executed at all, so verifying // valid, then some later input I1 might never have executed at all, so verifying
// it is still up to date is meaningless. // it is still up to date is meaningless.
let last_verified_at = old_memo.verified_at.load(); let last_verified_at = old_memo.verified_at.load();
for &QueryEdge { for &edge in edges.input_outputs.iter() {
kind, match edge {
dependency_index, QueryEdge::Input(dependency_index) => {
} in edges.input_outputs.iter()
{
match kind {
EdgeKind::Input => {
if dependency_index if dependency_index
.maybe_changed_after(db.as_dyn_database(), last_verified_at) .maybe_changed_after(db.as_dyn_database(), last_verified_at)
{ {
return false; return false;
} }
} }
EdgeKind::Output => { QueryEdge::Output(dependency_index) => {
// Subtle: Mark outputs as validated now, even though we may // Subtle: Mark outputs as validated now, even though we may
// later find an input that requires us to re-execute the function. // later find an input that requires us to re-execute the function.
// Even if it re-execute, the function will wind up writing the same value, // Even if it re-execute, the function will wind up writing the same value,

View file

@ -429,12 +429,6 @@ impl QueryOrigin {
} }
} }
#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash)]
pub enum EdgeKind {
Input,
Output,
}
/// The edges between a memoized value and other queries in the dependency graph. /// The edges between a memoized value and other queries in the dependency graph.
/// These edges include both dependency edges /// These edges include both dependency edges
/// e.g., when creating the memoized value for Q0 executed another function Q1) /// e.g., when creating the memoized value for Q0 executed another function Q1)
@ -459,25 +453,9 @@ pub struct QueryEdges {
} }
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
pub struct QueryEdge { pub enum QueryEdge {
pub kind: EdgeKind, Input(DependencyIndex),
pub dependency_index: DependencyIndex, Output(DependencyIndex),
}
impl QueryEdge {
pub(crate) fn input(input: DependencyIndex) -> QueryEdge {
QueryEdge {
kind: EdgeKind::Input,
dependency_index: input,
}
}
pub(crate) fn output(key: DependencyIndex) -> QueryEdge {
QueryEdge {
kind: EdgeKind::Output,
dependency_index: key,
}
}
} }
impl QueryEdges { impl QueryEdges {
@ -485,20 +463,20 @@ impl QueryEdges {
/// ///
/// These will always be in execution order. /// These will always be in execution order.
pub(crate) fn inputs(&self) -> impl DoubleEndedIterator<Item = DependencyIndex> + '_ { pub(crate) fn inputs(&self) -> impl DoubleEndedIterator<Item = DependencyIndex> + '_ {
self.input_outputs self.input_outputs.iter().filter_map(|&edge| match edge {
.iter() QueryEdge::Input(dependency_index) => Some(dependency_index),
.filter(|edge| edge.kind == EdgeKind::Input) QueryEdge::Output(_) => None,
.map(|edge| edge.dependency_index) })
} }
/// Returns the (tracked) outputs that were executed in computing this memoized value. /// Returns the (tracked) outputs that were executed in computing this memoized value.
/// ///
/// These will always be in execution order. /// These will always be in execution order.
pub(crate) fn outputs(&self) -> impl DoubleEndedIterator<Item = DependencyIndex> + '_ { pub(crate) fn outputs(&self) -> impl DoubleEndedIterator<Item = DependencyIndex> + '_ {
self.input_outputs self.input_outputs.iter().filter_map(|&edge| match edge {
.iter() QueryEdge::Output(dependency_index) => Some(dependency_index),
.filter(|edge| edge.kind == EdgeKind::Output) QueryEdge::Input(_) => None,
.map(|edge| edge.dependency_index) })
} }
/// Creates a new `QueryEdges`; the values given for each field must meet struct invariants. /// Creates a new `QueryEdges`; the values given for each field must meet struct invariants.