From 30026c8301788e1978889582931b0d2c0959137c Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Sat, 4 Jan 2025 15:05:12 +0100 Subject: [PATCH] Encapsulate `DependencyIndex` --- src/accumulator.rs | 4 ++-- src/function.rs | 5 ++--- src/function/diff_outputs.rs | 7 ++----- src/ingredient.rs | 4 ++-- src/input.rs | 9 +++------ src/input/input_field.rs | 4 ++-- src/interned.rs | 4 ++-- src/key.rs | 25 ++++++++++++++----------- src/tracked_struct.rs | 15 +++++---------- src/tracked_struct/tracked_field.rs | 4 ++-- 10 files changed, 36 insertions(+), 45 deletions(-) diff --git a/src/accumulator.rs b/src/accumulator.rs index 8cb38e2e..5da79420 100644 --- a/src/accumulator.rs +++ b/src/accumulator.rs @@ -122,7 +122,7 @@ impl Ingredient for IngredientImpl { &self, _db: &dyn Database, _executor: DatabaseKeyIndex, - _output_key: Option, + _output_key: crate::Id, ) { } @@ -130,7 +130,7 @@ impl Ingredient for IngredientImpl { &self, _db: &dyn Database, _executor: DatabaseKeyIndex, - _stale_output_key: Option, + _stale_output_key: crate::Id, ) { } diff --git a/src/function.rs b/src/function.rs index b06be486..7295f31f 100644 --- a/src/function.rs +++ b/src/function.rs @@ -212,9 +212,8 @@ where &self, db: &dyn Database, executor: DatabaseKeyIndex, - output_key: Option, + 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, + _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. diff --git a/src/function/diff_outputs.rs b/src/function/diff_outputs.rs index d89f0d52..7aab06a9 100644 --- a/src/function/diff_outputs.rs +++ b/src/function/diff_outputs.rs @@ -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)) }); } diff --git a/src/ingredient.rs b/src/ingredient.rs index 8a46205d..22f8e426 100644 --- a/src/ingredient.rs +++ b/src/ingredient.rs @@ -83,7 +83,7 @@ pub trait Ingredient: Any + std::fmt::Debug + Send + Sync { &'db self, db: &'db dyn Database, executor: DatabaseKeyIndex, - output_key: Option, + 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, + stale_output_key: Id, ); /// Returns the [`IngredientIndex`] of this ingredient. diff --git a/src/input.rs b/src/input.rs index eac540ab..05a0ec8a 100644 --- a/src/input.rs +++ b/src/input.rs @@ -191,10 +191,7 @@ impl IngredientImpl { 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 Ingredient for IngredientImpl { &self, _db: &dyn Database, executor: DatabaseKeyIndex, - output_key: Option, + output_key: Id, ) { unreachable!( "mark_validated_output({:?}, {:?}): input cannot be the output of a tracked function", @@ -252,7 +249,7 @@ impl Ingredient for IngredientImpl { &self, _db: &dyn Database, executor: DatabaseKeyIndex, - stale_output_key: Option, + stale_output_key: Id, ) { unreachable!( "remove_stale_output({:?}, {:?}): input cannot be the output of a tracked function", diff --git a/src/input/input_field.rs b/src/input/input_field.rs index fd308225..36d26ad4 100644 --- a/src/input/input_field.rs +++ b/src/input/input_field.rs @@ -69,7 +69,7 @@ where &self, _db: &dyn Database, _executor: DatabaseKeyIndex, - _output_key: Option, + _output_key: Id, ) { } @@ -77,7 +77,7 @@ where &self, _db: &dyn Database, _executor: DatabaseKeyIndex, - _stale_output_key: Option, + _stale_output_key: Id, ) { } diff --git a/src/interned.rs b/src/interned.rs index 62ef4fe6..4fa3a6d9 100644 --- a/src/interned.rs +++ b/src/interned.rs @@ -241,7 +241,7 @@ where &self, _db: &dyn Database, executor: DatabaseKeyIndex, - output_key: Option, + 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, + stale_output_key: crate::Id, ) { unreachable!( "remove_stale_output({:?}, {:?}): interned ids are not outputs", diff --git a/src/key.rs b/src/key.rs index 67ce3e3e..b7ee46e7 100644 --- a/src/key.rs +++ b/src/key.rs @@ -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, + ingredient_index: IngredientIndex, + key_index: Option, } 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 { - 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 { diff --git a/src/tracked_struct.rs b/src/tracked_struct.rs index 97d3f968..ad170ef1 100644 --- a/src/tracked_struct.rs +++ b/src/tracked_struct.rs @@ -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, + _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, + 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, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { diff --git a/src/tracked_struct/tracked_field.rs b/src/tracked_struct/tracked_field.rs index ff190939..4ba93fc4 100644 --- a/src/tracked_struct/tracked_field.rs +++ b/src/tracked_struct/tracked_field.rs @@ -73,7 +73,7 @@ where &self, _db: &dyn Database, _executor: crate::DatabaseKeyIndex, - _output_key: Option, + _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, + _stale_output_key: crate::Id, ) { panic!("tracked field ingredients have no outputs") }