mirror of
https://github.com/salsa-rs/salsa.git
synced 2025-02-02 09:46:06 +00:00
Fix query invalidation when high durability input changes
This commit is contained in:
parent
994c988739
commit
a263dd04ba
5 changed files with 61 additions and 14 deletions
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
11
src/input.rs
11
src/input.rs
|
@ -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)
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
})
|
||||
}
|
||||
|
|
10
src/zalsa.rs
10
src/zalsa.rs
|
@ -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**
|
||||
|
|
36
tests/tracked_fn_high_durability_dependency.rs
Normal file
36
tests/tracked_fn_high_durability_dependency.rs
Normal 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);
|
||||
}
|
Loading…
Reference in a new issue