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

View file

@ -212,9 +212,8 @@ where
&self,
db: &dyn Database,
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);
}
@ -222,7 +221,7 @@ where
&self,
_db: &dyn Database,
_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,
// 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() {
// 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.
revisions.tracked_struct_ids.retain(|k, value| {
!old_outputs.contains(&DependencyIndex {
ingredient_index: k.ingredient_index(),
key_index: Some(*value),
})
revisions.tracked_struct_ids.retain(|&k, &mut value| {
!old_outputs.contains(&DependencyIndex::new(k.ingredient_index(), value))
});
}

View file

@ -83,7 +83,7 @@ pub trait Ingredient: Any + std::fmt::Debug + Send + Sync {
&'db self,
db: &'db dyn Database,
executor: DatabaseKeyIndex,
output_key: Option<Id>,
output_key: crate::Id,
);
/// 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,
db: &dyn Database,
executor: DatabaseKeyIndex,
stale_output_key: Option<Id>,
stale_output_key: Id,
);
/// Returns the [`IngredientIndex`] of this ingredient.

View file

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

View file

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

View file

@ -241,7 +241,7 @@ where
&self,
_db: &dyn Database,
executor: DatabaseKeyIndex,
output_key: Option<crate::Id>,
output_key: crate::Id,
) {
unreachable!(
"mark_validated_output({:?}, {:?}): input cannot be the output of a tracked function",
@ -253,7 +253,7 @@ where
&self,
_db: &dyn Database,
executor: DatabaseKeyIndex,
stale_output_key: Option<crate::Id>,
stale_output_key: crate::Id,
) {
unreachable!(
"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.
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct DependencyIndex {
pub(crate) ingredient_index: IngredientIndex,
pub(crate) key_index: Option<Id>,
ingredient_index: IngredientIndex,
key_index: Option<Id>,
}
impl DependencyIndex {
/// 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
/// remains valid until the table as a whole is reset. Using a single id avoids
/// creating tons of dependencies in the dependency listings.
@ -23,18 +23,17 @@ impl DependencyIndex {
}
}
pub fn ingredient_index(self) -> IngredientIndex {
self.ingredient_index
}
pub fn key_index(self) -> Option<Id> {
self.key_index
pub(crate) fn new(ingredient_index: IngredientIndex, key_index: Id) -> Self {
Self {
ingredient_index,
key_index: Some(key_index),
}
}
pub(crate) fn remove_stale_output(&self, db: &dyn Database, executor: DatabaseKeyIndex) {
db.zalsa()
.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(
@ -44,7 +43,7 @@ impl DependencyIndex {
) {
db.zalsa()
.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(
@ -56,6 +55,10 @@ impl DependencyIndex {
.lookup_ingredient(self.ingredient_index)
.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 {

View file

@ -520,9 +520,7 @@ where
});
for stale_output in memo.origin().outputs() {
zalsa
.lookup_ingredient(stale_output.ingredient_index)
.remove_stale_output(db, executor, stale_output.key_index);
stale_output.remove_stale_output(db, executor);
}
}
@ -561,10 +559,7 @@ where
let field_changed_at = data.revisions[field_index];
zalsa_local.report_tracked_read(
DependencyIndex {
ingredient_index: field_ingredient_index,
key_index: Some(id),
},
DependencyIndex::new(field_ingredient_index, id),
data.durability,
field_changed_at,
InputAccumulatedValues::Empty,
@ -603,7 +598,7 @@ where
&'db self,
_db: &'db dyn Database,
_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
//
@ -614,13 +609,13 @@ where
&self,
db: &dyn Database,
_executor: DatabaseKeyIndex,
stale_output_key: Option<crate::Id>,
stale_output_key: crate::Id,
) {
// This method is called when, in prior revisions,
// `executor` creates a tracked struct `salsa_output_key`,
// but it did not in the current revision.
// 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 {

View file

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