Revert "track both inputs/outputs for each query"

This reverts commit 49ccac5d3d.
This commit is contained in:
Niko Matsakis 2022-08-12 14:28:26 -04:00
parent afefcdf335
commit cb0b53caa7
16 changed files with 46 additions and 92 deletions

View file

@ -136,7 +136,7 @@ fn has_jars_dyn_impl(input: &syn::ItemStruct, storage: &syn::Ident) -> syn::Item
fn inputs(
&self,
index: salsa::DatabaseKeyIndex,
) -> Option<salsa::runtime::local_state::QueryEdges> {
) -> Option<salsa::runtime::local_state::QueryInputs> {
let ingredient = self.#storage.ingredient(index.ingredient_index());
ingredient.inputs(index.key_index())
}

View file

@ -3,7 +3,7 @@ use crate::{
hash::FxDashMap,
ingredient::{Ingredient, MutIngredient},
key::DependencyIndex,
runtime::{local_state::QueryEdges, StampedValue},
runtime::{local_state::QueryInputs, StampedValue},
storage::HasJar,
DatabaseKeyIndex, Durability, IngredientIndex, Revision, Runtime,
};
@ -78,7 +78,7 @@ where
CycleRecoveryStrategy::Panic
}
fn inputs(&self, _key_index: crate::Id) -> Option<QueryEdges> {
fn inputs(&self, _key_index: crate::Id) -> Option<QueryInputs> {
None
}
}

View file

@ -8,7 +8,7 @@ use crate::{
ingredient::MutIngredient,
jar::Jar,
key::{DatabaseKeyIndex, DependencyIndex},
runtime::local_state::QueryEdges,
runtime::local_state::QueryInputs,
salsa_struct::SalsaStructInDb,
Cycle, DbWithJar, Id, Revision,
};
@ -198,7 +198,7 @@ where
C::CYCLE_STRATEGY
}
fn inputs(&self, key_index: Id) -> Option<QueryEdges> {
fn inputs(&self, key_index: Id) -> Option<QueryInputs> {
let key = C::key_from_id(key_index);
self.inputs(key)
}

View file

@ -1,7 +1,7 @@
use crate::{
hash::FxHashSet,
key::DependencyIndex,
runtime::local_state::QueryEdges,
runtime::local_state::QueryInputs,
storage::{HasJar, HasJarsDyn},
Database, DatabaseKeyIndex,
};
@ -55,7 +55,7 @@ impl Stack {
self.v.pop()
}
fn extend(&mut self, inputs: Option<QueryEdges>) {
fn extend(&mut self, inputs: Option<QueryInputs>) {
let inputs = match inputs {
None => return,
Some(v) => v,
@ -64,7 +64,7 @@ impl Stack {
for DependencyIndex {
ingredient_index,
key_index,
} in inputs.inputs().iter().copied()
} in inputs.tracked.iter().copied()
{
if let Some(key_index) = key_index {
let i = DatabaseKeyIndex {

View file

@ -93,7 +93,7 @@ where
if let Some(memo) = self.memo_map.get(key) {
// Careful: we can't evict memos with untracked inputs
// as their values cannot be reconstructed.
if memo.revisions.edges.untracked {
if memo.revisions.inputs.untracked {
return;
}

View file

@ -1,4 +1,4 @@
use crate::runtime::local_state::QueryEdges;
use crate::runtime::local_state::QueryInputs;
use super::{Configuration, FunctionIngredient};
@ -6,7 +6,7 @@ impl<C> FunctionIngredient<C>
where
C: Configuration,
{
pub(super) fn inputs(&self, key: C::Key) -> Option<QueryEdges> {
self.memo_map.get(key).map(|m| m.revisions.edges.clone())
pub(super) fn inputs(&self, key: C::Key) -> Option<QueryInputs> {
self.memo_map.get(key).map(|m| m.revisions.inputs.clone())
}
}

View file

@ -158,13 +158,13 @@ where
return true;
}
if old_memo.revisions.edges.untracked {
if old_memo.revisions.inputs.untracked {
// Untracked inputs? Have to assume that it changed.
return false;
}
let last_verified_at = old_memo.verified_at.load();
for &input in old_memo.revisions.edges.inputs().iter() {
for &input in old_memo.revisions.inputs.tracked.iter() {
if db.maybe_changed_after(input, last_verified_at) {
return false;
}

View file

@ -1,7 +1,7 @@
use crossbeam::atomic::AtomicCell;
use crate::{
runtime::local_state::{QueryEdges, QueryRevisions},
runtime::local_state::{QueryInputs, QueryRevisions},
tracked_struct::TrackedStructInDb,
Database,
};
@ -49,17 +49,16 @@ where
//
// - a result that is verified in the current revision, because it was set, which will use the set value
// - a result that is NOT verified and has untracked inputs, which will re-execute (and likely panic)
let edges = QueryEdges {
let inputs = QueryInputs {
untracked: false,
separator: 0,
input_outputs: runtime.empty_dependencies(),
tracked: runtime.empty_dependencies(),
};
let revision = runtime.current_revision();
let mut revisions = QueryRevisions {
changed_at: current_deps.changed_at,
durability: current_deps.durability,
edges,
inputs,
};
if let Some(old_memo) = self.memo_map.get(key) {

View file

@ -4,7 +4,7 @@ use crossbeam::atomic::AtomicCell;
use crate::{
durability::Durability,
runtime::local_state::{QueryEdges, QueryRevisions},
runtime::local_state::{QueryInputs, QueryRevisions},
Runtime,
};
@ -28,10 +28,9 @@ where
revisions: QueryRevisions {
changed_at: revision,
durability,
edges: QueryEdges {
inputs: QueryInputs {
untracked: false,
separator: 0,
input_outputs: runtime.empty_dependencies(),
tracked: runtime.empty_dependencies(),
},
},
};

View file

@ -1,5 +1,5 @@
use crate::{
cycle::CycleRecoveryStrategy, key::DependencyIndex, runtime::local_state::QueryEdges, Id,
cycle::CycleRecoveryStrategy, key::DependencyIndex, runtime::local_state::QueryInputs, Id,
};
use super::Revision;
@ -21,7 +21,7 @@ pub trait Ingredient<DB: ?Sized> {
fn maybe_changed_after(&self, db: &DB, input: DependencyIndex, revision: Revision) -> bool;
/// What were the inputs (if any) that were used to create the value at `key_index`.
fn inputs(&self, key_index: Id) -> Option<QueryEdges>;
fn inputs(&self, key_index: Id) -> Option<QueryInputs>;
}
/// Optional trait for ingredients that wish to be notified when new revisions are

View file

@ -2,7 +2,7 @@ use crate::{
cycle::CycleRecoveryStrategy,
ingredient::Ingredient,
key::{DatabaseKeyIndex, DependencyIndex},
runtime::{local_state::QueryEdges, Runtime},
runtime::{local_state::QueryInputs, Runtime},
AsId, IngredientIndex, Revision,
};
@ -58,7 +58,7 @@ where
CycleRecoveryStrategy::Panic
}
fn inputs(&self, _key_index: crate::Id) -> Option<QueryEdges> {
fn inputs(&self, _key_index: crate::Id) -> Option<QueryInputs> {
None
}
}

View file

@ -6,7 +6,7 @@ use std::marker::PhantomData;
use crate::durability::Durability;
use crate::id::AsId;
use crate::key::DependencyIndex;
use crate::runtime::local_state::QueryEdges;
use crate::runtime::local_state::QueryInputs;
use crate::runtime::Runtime;
use super::hash::FxDashMap;
@ -194,7 +194,7 @@ where
crate::cycle::CycleRecoveryStrategy::Panic
}
fn inputs(&self, _key_index: crate::Id) -> Option<QueryEdges> {
fn inputs(&self, _key_index: crate::Id) -> Option<QueryInputs> {
None
}
}

View file

@ -8,7 +8,7 @@ use crate::{
Cycle, Revision, Runtime,
};
use super::local_state::{QueryEdges, QueryRevisions};
use super::local_state::{QueryInputs, QueryRevisions};
#[derive(Debug)]
pub(super) struct ActiveQuery {
@ -95,27 +95,18 @@ impl ActiveQuery {
}
pub(crate) fn revisions(&self, runtime: &Runtime) -> QueryRevisions {
let separator = u32::try_from(self.dependencies.len()).unwrap();
let input_outputs = if self.dependencies.is_empty() && self.outputs.is_empty() {
runtime.empty_dependencies()
} else {
self.dependencies
.iter()
.copied()
.chain(self.outputs.iter().map(|&o| o.into()))
.collect()
};
let edges = QueryEdges {
let inputs = QueryInputs {
untracked: self.untracked_read,
separator,
input_outputs,
tracked: if self.dependencies.is_empty() {
runtime.empty_dependencies()
} else {
self.dependencies.iter().copied().collect()
},
};
QueryRevisions {
changed_at: self.changed_at,
edges,
inputs,
durability: self.durability,
}
}

View file

@ -40,7 +40,7 @@ pub(crate) struct QueryRevisions {
pub(crate) durability: Durability,
/// The inputs that went into our query, if we are tracking them.
pub(crate) edges: QueryEdges,
pub(crate) inputs: QueryInputs,
}
impl QueryRevisions {
@ -53,53 +53,18 @@ impl QueryRevisions {
}
}
/// The edges between a memoized value and other queries in the dependency graph.
/// These edges include both dependency edges
/// e.g., when creating the memoized value for Q0 executed another function Q1)
/// and output edges
/// (e.g., when Q0 specified the value for another query Q2).
/// Every input.
#[derive(Debug, Clone)]
pub struct QueryEdges {
/// The list of outgoing edges from this node.
/// This list combines *both* inputs and outputs.
/// The inputs are defined from the indices `0..S` where
/// `S` is the value of the `separator` field.
///
/// Note that we always track input dependencies even when there are untracked reads.
/// Untracked reads mean that we can't verify values, so we don't use the list of inputs for that,
/// but we still use it for finding the transitive inputs to an accumulator.
///
/// You can access the input/output list via the methods [`inputs`] and [`outputs`] respectively.
///
/// Important:
///
/// * The inputs must be in **execution order** for the red-green algorithm to work.
/// * The outputs must be in **sorted order** so that we can easily "diff" them between revisions.
pub(crate) input_outputs: Arc<[DependencyIndex]>,
/// The index that separates inputs from outputs in the `tracked` field.
pub(crate) separator: u32,
pub struct QueryInputs {
/// Inputs that are fully known.
/// We track these even if there are unknown inputs so that the accumulator code
/// can walk all the inputs even for tracked functions that read untracked values.
pub(crate) tracked: Arc<[DependencyIndex]>,
/// Where there any *unknown* inputs?
pub(crate) untracked: bool,
}
impl QueryEdges {
/// Returns the (tracked) inputs that were executed in computing this memoized value.
///
/// These will always be in execution order.
pub(crate) fn inputs(&self) -> &[DependencyIndex] {
&self.input_outputs[0..self.separator as usize]
}
/// Returns the queries whose values were assigned while computing this memoized value.
///
/// These will always be in sorted order.
pub(crate) fn outputs(&self) -> &[DependencyIndex] {
&self.input_outputs[self.separator as usize..]
}
}
impl Default for LocalState {
fn default() -> Self {
LocalState {

View file

@ -6,7 +6,7 @@ use crate::cycle::CycleRecoveryStrategy;
use crate::ingredient::Ingredient;
use crate::jar::Jar;
use crate::key::DependencyIndex;
use crate::runtime::local_state::QueryEdges;
use crate::runtime::local_state::QueryInputs;
use crate::runtime::Runtime;
use crate::{Database, DatabaseKeyIndex, IngredientIndex};
@ -178,7 +178,7 @@ pub trait HasJarsDyn {
fn cycle_recovery_strategy(&self, input: IngredientIndex) -> CycleRecoveryStrategy;
fn inputs(&self, input: DatabaseKeyIndex) -> Option<QueryEdges>;
fn inputs(&self, input: DatabaseKeyIndex) -> Option<QueryInputs>;
}
pub trait HasIngredientsFor<I>

View file

@ -3,7 +3,7 @@ use crate::{
ingredient::{Ingredient, MutIngredient},
interned::{InternedData, InternedId, InternedIngredient},
key::{DatabaseKeyIndex, DependencyIndex},
runtime::{local_state::QueryEdges, Runtime},
runtime::{local_state::QueryInputs, Runtime},
salsa_struct::SalsaStructInDb,
Database, IngredientIndex, Revision,
};
@ -114,7 +114,7 @@ where
<_ as Ingredient<DB>>::cycle_recovery_strategy(&self.interned)
}
fn inputs(&self, _key_index: crate::Id) -> Option<QueryEdges> {
fn inputs(&self, _key_index: crate::Id) -> Option<QueryInputs> {
None
}
}