Merge pull request #557 from MichaReiser/high-durability-write
Some checks are pending
Book / Book (push) Waiting to run
Book / Deploy (push) Blocked by required conditions
Test / Test (false, beta) (push) Waiting to run
Test / Test (false, stable) (push) Waiting to run
Test / Test (true, nightly) (push) Waiting to run
Test / Miri (push) Waiting to run
Test / Benchmarks (push) Waiting to run

Fix query invalidation when high durability input changes
This commit is contained in:
Micha Reiser 2024-08-05 16:36:21 +00:00 committed by GitHub
commit d6df21fba1
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 61 additions and 14 deletions

View file

@ -86,13 +86,13 @@ macro_rules! setup_input_struct {
})
}
pub fn ingredient_mut(db: &mut dyn $zalsa::Database) -> (&mut $zalsa_struct::IngredientImpl<Self>, $zalsa::Revision) {
pub fn ingredient_mut(db: &mut dyn $zalsa::Database) -> (&mut $zalsa_struct::IngredientImpl<Self>, &mut $zalsa::Runtime) {
let zalsa_mut = db.zalsa_mut();
let index = zalsa_mut.add_or_lookup_jar_by_type(&<$zalsa_struct::JarImpl<$Configuration>>::default());
let current_revision = zalsa_mut.current_revision();
let ingredient = zalsa_mut.lookup_ingredient_mut(index);
let (ingredient, runtime) = zalsa_mut.lookup_ingredient_mut(index);
let ingredient = ingredient.assert_type_mut::<$zalsa_struct::IngredientImpl<Self>>();
(ingredient, current_revision)
(ingredient, runtime)
}
}

View file

@ -20,7 +20,7 @@ use crate::{
plumbing::{Jar, Stamp},
zalsa::IngredientIndex,
zalsa_local::QueryOrigin,
Database, Durability, Id, Revision,
Database, Durability, Id, Revision, Runtime,
};
pub trait Configuration: Any {
@ -120,7 +120,7 @@ impl<C: Configuration> IngredientImpl<C> {
/// * `setter`, function that modifies the fields tuple; should only modify the element for `field_index`
pub fn set_field<R>(
&mut self,
current_revision: Revision,
runtime: &mut Runtime,
id: C::Struct,
field_index: usize,
durability: Durability,
@ -129,8 +129,13 @@ impl<C: Configuration> IngredientImpl<C> {
let id: Id = id.as_id();
let mut r = self.struct_map.update(id);
let stamp = &mut r.stamps[field_index];
if stamp.durability != Durability::LOW {
runtime.report_tracked_write(stamp.durability);
}
stamp.durability = durability;
stamp.changed_at = current_revision;
stamp.changed_at = runtime.current_revision();
setter(&mut r.fields)
}

View file

@ -1,7 +1,7 @@
use std::marker::PhantomData;
use crate::input::{Configuration, IngredientImpl};
use crate::{Durability, Revision};
use crate::{Durability, Runtime};
/// Setter for a field of an input.
pub trait Setter: Sized {
@ -12,7 +12,7 @@ pub trait Setter: Sized {
#[must_use]
pub struct SetterImpl<'setter, C: Configuration, S, F> {
current_revision: Revision,
runtime: &'setter mut Runtime,
id: C::Struct,
ingredient: &'setter mut IngredientImpl<C>,
durability: Durability,
@ -27,14 +27,14 @@ where
S: FnOnce(&mut C::Fields, F) -> F,
{
pub fn new(
current_revision: Revision,
runtime: &'setter mut Runtime,
id: C::Struct,
field_index: usize,
ingredient: &'setter mut IngredientImpl<C>,
setter: S,
) -> Self {
SetterImpl {
current_revision,
runtime,
id,
field_index,
ingredient,
@ -59,7 +59,7 @@ where
fn to(self, value: F) -> F {
let Self {
current_revision,
runtime,
id,
ingredient,
durability,
@ -68,7 +68,7 @@ where
phantom: _,
} = self;
ingredient.set_field(current_revision, id, field_index, durability, |tuple| {
ingredient.set_field(runtime, id, field_index, durability, |tuple| {
setter(tuple, value)
})
}

View file

@ -172,8 +172,14 @@ impl Zalsa {
}
/// **NOT SEMVER STABLE**
pub fn lookup_ingredient_mut(&mut self, index: IngredientIndex) -> &mut dyn Ingredient {
&mut **self.ingredients_vec.get_mut(index.as_usize()).unwrap()
pub fn lookup_ingredient_mut(
&mut self,
index: IngredientIndex,
) -> (&mut dyn Ingredient, &mut Runtime) {
(
&mut **self.ingredients_vec.get_mut(index.as_usize()).unwrap(),
&mut self.runtime,
)
}
/// **NOT SEMVER STABLE**

View file

@ -0,0 +1,36 @@
#![allow(warnings)]
use salsa::plumbing::HasStorage;
use salsa::{Database, Durability, Setter};
mod common;
#[salsa::input]
struct MyInput {
field: u32,
}
#[salsa::tracked]
fn tracked_fn(db: &dyn salsa::Database, input: MyInput) -> u32 {
input.field(db) * 2
}
#[test]
fn execute() {
let mut db = salsa::DatabaseImpl::default();
let input_high = MyInput::new(&mut db, 0);
input_high
.set_field(&mut db)
.with_durability(Durability::HIGH)
.to(2200);
assert_eq!(tracked_fn(&db, input_high), 4400);
// Changing the value should re-execute the query
input_high
.set_field(&mut db)
.with_durability(Durability::HIGH)
.to(2201);
assert_eq!(tracked_fn(&db, input_high), 4402);
}