Encapsulate DependencyIndex

This commit is contained in:
Lukas Wirth 2025-01-04 15:05:12 +01:00
parent 6c0dd82119
commit 30026c8301
10 changed files with 36 additions and 45 deletions

View file

@ -122,7 +122,7 @@ impl<A: Accumulator> Ingredient for IngredientImpl<A> {
&self, &self,
_db: &dyn Database, _db: &dyn Database,
_executor: DatabaseKeyIndex, _executor: DatabaseKeyIndex,
_output_key: Option<crate::Id>, _output_key: crate::Id,
) { ) {
} }
@ -130,7 +130,7 @@ impl<A: Accumulator> Ingredient for IngredientImpl<A> {
&self, &self,
_db: &dyn Database, _db: &dyn Database,
_executor: DatabaseKeyIndex, _executor: DatabaseKeyIndex,
_stale_output_key: Option<crate::Id>, _stale_output_key: crate::Id,
) { ) {
} }

View file

@ -212,9 +212,8 @@ where
&self, &self,
db: &dyn Database, db: &dyn Database,
executor: DatabaseKeyIndex, executor: DatabaseKeyIndex,
output_key: Option<crate::Id>, output_key: crate::Id,
) { ) {
let output_key = output_key.unwrap();
self.validate_specified_value(db, executor, output_key); self.validate_specified_value(db, executor, output_key);
} }
@ -222,7 +221,7 @@ where
&self, &self,
_db: &dyn Database, _db: &dyn Database,
_executor: DatabaseKeyIndex, _executor: DatabaseKeyIndex,
_stale_output_key: Option<crate::Id>, _stale_output_key: crate::Id,
) { ) {
// This function is invoked when a query Q specifies the value for `stale_output_key` in rev 1, // This function is invoked when a query Q specifies the value for `stale_output_key` in rev 1,
// but not in rev 2. We don't do anything in this case, we just leave the (now stale) memo. // but not in rev 2. We don't do anything in this case, we just leave the (now stale) memo.

View file

@ -32,11 +32,8 @@ where
if !old_outputs.is_empty() { if !old_outputs.is_empty() {
// Remove the outputs that are no longer present in the current revision // Remove the outputs that are no longer present in the current revision
// to prevent that the next revision is seeded with a id mapping that no longer exists. // to prevent that the next revision is seeded with a id mapping that no longer exists.
revisions.tracked_struct_ids.retain(|k, value| { revisions.tracked_struct_ids.retain(|&k, &mut value| {
!old_outputs.contains(&DependencyIndex { !old_outputs.contains(&DependencyIndex::new(k.ingredient_index(), value))
ingredient_index: k.ingredient_index(),
key_index: Some(*value),
})
}); });
} }

View file

@ -83,7 +83,7 @@ pub trait Ingredient: Any + std::fmt::Debug + Send + Sync {
&'db self, &'db self,
db: &'db dyn Database, db: &'db dyn Database,
executor: DatabaseKeyIndex, executor: DatabaseKeyIndex,
output_key: Option<Id>, output_key: crate::Id,
); );
/// Invoked when the value `stale_output` was output by `executor` in a previous /// Invoked when the value `stale_output` was output by `executor` in a previous
@ -94,7 +94,7 @@ pub trait Ingredient: Any + std::fmt::Debug + Send + Sync {
&self, &self,
db: &dyn Database, db: &dyn Database,
executor: DatabaseKeyIndex, executor: DatabaseKeyIndex,
stale_output_key: Option<Id>, stale_output_key: Id,
); );
/// Returns the [`IngredientIndex`] of this ingredient. /// Returns the [`IngredientIndex`] of this ingredient.

View file

@ -191,10 +191,7 @@ impl<C: Configuration> IngredientImpl<C> {
let value = Self::data(zalsa, id); let value = Self::data(zalsa, id);
let stamp = &value.stamps[field_index]; let stamp = &value.stamps[field_index];
zalsa_local.report_tracked_read( zalsa_local.report_tracked_read(
DependencyIndex { DependencyIndex::new(field_ingredient_index, id),
ingredient_index: field_ingredient_index,
key_index: Some(id),
},
stamp.durability, stamp.durability,
stamp.changed_at, stamp.changed_at,
InputAccumulatedValues::Empty, InputAccumulatedValues::Empty,
@ -240,7 +237,7 @@ impl<C: Configuration> Ingredient for IngredientImpl<C> {
&self, &self,
_db: &dyn Database, _db: &dyn Database,
executor: DatabaseKeyIndex, executor: DatabaseKeyIndex,
output_key: Option<Id>, output_key: Id,
) { ) {
unreachable!( unreachable!(
"mark_validated_output({:?}, {:?}): input cannot be the output of a tracked function", "mark_validated_output({:?}, {:?}): input cannot be the output of a tracked function",
@ -252,7 +249,7 @@ impl<C: Configuration> Ingredient for IngredientImpl<C> {
&self, &self,
_db: &dyn Database, _db: &dyn Database,
executor: DatabaseKeyIndex, executor: DatabaseKeyIndex,
stale_output_key: Option<Id>, stale_output_key: Id,
) { ) {
unreachable!( unreachable!(
"remove_stale_output({:?}, {:?}): input cannot be the output of a tracked function", "remove_stale_output({:?}, {:?}): input cannot be the output of a tracked function",

View file

@ -69,7 +69,7 @@ where
&self, &self,
_db: &dyn Database, _db: &dyn Database,
_executor: DatabaseKeyIndex, _executor: DatabaseKeyIndex,
_output_key: Option<Id>, _output_key: Id,
) { ) {
} }
@ -77,7 +77,7 @@ where
&self, &self,
_db: &dyn Database, _db: &dyn Database,
_executor: DatabaseKeyIndex, _executor: DatabaseKeyIndex,
_stale_output_key: Option<Id>, _stale_output_key: Id,
) { ) {
} }

View file

@ -241,7 +241,7 @@ where
&self, &self,
_db: &dyn Database, _db: &dyn Database,
executor: DatabaseKeyIndex, executor: DatabaseKeyIndex,
output_key: Option<crate::Id>, output_key: crate::Id,
) { ) {
unreachable!( unreachable!(
"mark_validated_output({:?}, {:?}): input cannot be the output of a tracked function", "mark_validated_output({:?}, {:?}): input cannot be the output of a tracked function",
@ -253,7 +253,7 @@ where
&self, &self,
_db: &dyn Database, _db: &dyn Database,
executor: DatabaseKeyIndex, executor: DatabaseKeyIndex,
stale_output_key: Option<crate::Id>, stale_output_key: crate::Id,
) { ) {
unreachable!( unreachable!(
"remove_stale_output({:?}, {:?}): interned ids are not outputs", "remove_stale_output({:?}, {:?}): interned ids are not outputs",

View file

@ -6,13 +6,13 @@ use crate::{cycle::CycleRecoveryStrategy, zalsa::IngredientIndex, Database, Id};
/// inserting into maps and the like. /// inserting into maps and the like.
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct DependencyIndex { pub struct DependencyIndex {
pub(crate) ingredient_index: IngredientIndex, ingredient_index: IngredientIndex,
pub(crate) key_index: Option<Id>, key_index: Option<Id>,
} }
impl DependencyIndex { impl DependencyIndex {
/// Create a database-key-index for an interning or entity table. /// Create a database-key-index for an interning or entity table.
/// The `key_index` here is always zero, which deliberately corresponds to /// The `key_index` here is always `None`, which deliberately corresponds to
/// no particular id or entry. This is because the data in such tables /// no particular id or entry. This is because the data in such tables
/// remains valid until the table as a whole is reset. Using a single id avoids /// remains valid until the table as a whole is reset. Using a single id avoids
/// creating tons of dependencies in the dependency listings. /// creating tons of dependencies in the dependency listings.
@ -23,18 +23,17 @@ impl DependencyIndex {
} }
} }
pub fn ingredient_index(self) -> IngredientIndex { pub(crate) fn new(ingredient_index: IngredientIndex, key_index: Id) -> Self {
self.ingredient_index Self {
} ingredient_index,
key_index: Some(key_index),
pub fn key_index(self) -> Option<Id> { }
self.key_index
} }
pub(crate) fn remove_stale_output(&self, db: &dyn Database, executor: DatabaseKeyIndex) { pub(crate) fn remove_stale_output(&self, db: &dyn Database, executor: DatabaseKeyIndex) {
db.zalsa() db.zalsa()
.lookup_ingredient(self.ingredient_index) .lookup_ingredient(self.ingredient_index)
.remove_stale_output(db, executor, self.key_index) .remove_stale_output(db, executor, self.key_index.unwrap())
} }
pub(crate) fn mark_validated_output( pub(crate) fn mark_validated_output(
@ -44,7 +43,7 @@ impl DependencyIndex {
) { ) {
db.zalsa() db.zalsa()
.lookup_ingredient(self.ingredient_index) .lookup_ingredient(self.ingredient_index)
.mark_validated_output(db, database_key_index, self.key_index) .mark_validated_output(db, database_key_index, self.key_index.unwrap())
} }
pub(crate) fn maybe_changed_after( pub(crate) fn maybe_changed_after(
@ -56,6 +55,10 @@ impl DependencyIndex {
.lookup_ingredient(self.ingredient_index) .lookup_ingredient(self.ingredient_index)
.maybe_changed_after(db, self.key_index, last_verified_at) .maybe_changed_after(db, self.key_index, last_verified_at)
} }
pub fn set_key_index(&mut self, key_index: Id) {
self.key_index = Some(key_index);
}
} }
impl std::fmt::Debug for DependencyIndex { impl std::fmt::Debug for DependencyIndex {

View file

@ -520,9 +520,7 @@ where
}); });
for stale_output in memo.origin().outputs() { for stale_output in memo.origin().outputs() {
zalsa stale_output.remove_stale_output(db, executor);
.lookup_ingredient(stale_output.ingredient_index)
.remove_stale_output(db, executor, stale_output.key_index);
} }
} }
@ -561,10 +559,7 @@ where
let field_changed_at = data.revisions[field_index]; let field_changed_at = data.revisions[field_index];
zalsa_local.report_tracked_read( zalsa_local.report_tracked_read(
DependencyIndex { DependencyIndex::new(field_ingredient_index, id),
ingredient_index: field_ingredient_index,
key_index: Some(id),
},
data.durability, data.durability,
field_changed_at, field_changed_at,
InputAccumulatedValues::Empty, InputAccumulatedValues::Empty,
@ -603,7 +598,7 @@ where
&'db self, &'db self,
_db: &'db dyn Database, _db: &'db dyn Database,
_executor: DatabaseKeyIndex, _executor: DatabaseKeyIndex,
_output_key: Option<crate::Id>, _output_key: crate::Id,
) { ) {
// we used to update `update_at` field but now we do it lazilly when data is accessed // we used to update `update_at` field but now we do it lazilly when data is accessed
// //
@ -614,13 +609,13 @@ where
&self, &self,
db: &dyn Database, db: &dyn Database,
_executor: DatabaseKeyIndex, _executor: DatabaseKeyIndex,
stale_output_key: Option<crate::Id>, stale_output_key: crate::Id,
) { ) {
// This method is called when, in prior revisions, // This method is called when, in prior revisions,
// `executor` creates a tracked struct `salsa_output_key`, // `executor` creates a tracked struct `salsa_output_key`,
// but it did not in the current revision. // but it did not in the current revision.
// In that case, we can delete `stale_output_key` and any data associated with it. // In that case, we can delete `stale_output_key` and any data associated with it.
self.delete_entity(db.as_dyn_database(), stale_output_key.unwrap()); self.delete_entity(db.as_dyn_database(), stale_output_key);
} }
fn fmt_index(&self, index: Option<crate::Id>, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt_index(&self, index: Option<crate::Id>, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {

View file

@ -73,7 +73,7 @@ where
&self, &self,
_db: &dyn Database, _db: &dyn Database,
_executor: crate::DatabaseKeyIndex, _executor: crate::DatabaseKeyIndex,
_output_key: Option<crate::Id>, _output_key: crate::Id,
) { ) {
panic!("tracked field ingredients have no outputs") panic!("tracked field ingredients have no outputs")
} }
@ -82,7 +82,7 @@ where
&self, &self,
_db: &dyn Database, _db: &dyn Database,
_executor: crate::DatabaseKeyIndex, _executor: crate::DatabaseKeyIndex,
_stale_output_key: Option<crate::Id>, _stale_output_key: crate::Id,
) { ) {
panic!("tracked field ingredients have no outputs") panic!("tracked field ingredients have no outputs")
} }