Skip to content

Commit d6df21f

Browse files
authored
Merge pull request #557 from MichaReiser/high-durability-write
Fix query invalidation when high durability input changes
2 parents c830be2 + a263dd0 commit d6df21f

File tree

5 files changed

+61
-14
lines changed

5 files changed

+61
-14
lines changed

components/salsa-macro-rules/src/setup_input_struct.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -86,13 +86,13 @@ macro_rules! setup_input_struct {
8686
})
8787
}
8888

89-
pub fn ingredient_mut(db: &mut dyn $zalsa::Database) -> (&mut $zalsa_struct::IngredientImpl<Self>, $zalsa::Revision) {
89+
pub fn ingredient_mut(db: &mut dyn $zalsa::Database) -> (&mut $zalsa_struct::IngredientImpl<Self>, &mut $zalsa::Runtime) {
9090
let zalsa_mut = db.zalsa_mut();
9191
let index = zalsa_mut.add_or_lookup_jar_by_type(&<$zalsa_struct::JarImpl<$Configuration>>::default());
9292
let current_revision = zalsa_mut.current_revision();
93-
let ingredient = zalsa_mut.lookup_ingredient_mut(index);
93+
let (ingredient, runtime) = zalsa_mut.lookup_ingredient_mut(index);
9494
let ingredient = ingredient.assert_type_mut::<$zalsa_struct::IngredientImpl<Self>>();
95-
(ingredient, current_revision)
95+
(ingredient, runtime)
9696
}
9797
}
9898

src/input.rs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ use crate::{
2020
plumbing::{Jar, Stamp},
2121
zalsa::IngredientIndex,
2222
zalsa_local::QueryOrigin,
23-
Database, Durability, Id, Revision,
23+
Database, Durability, Id, Revision, Runtime,
2424
};
2525

2626
pub trait Configuration: Any {
@@ -120,7 +120,7 @@ impl<C: Configuration> IngredientImpl<C> {
120120
/// * `setter`, function that modifies the fields tuple; should only modify the element for `field_index`
121121
pub fn set_field<R>(
122122
&mut self,
123-
current_revision: Revision,
123+
runtime: &mut Runtime,
124124
id: C::Struct,
125125
field_index: usize,
126126
durability: Durability,
@@ -129,8 +129,13 @@ impl<C: Configuration> IngredientImpl<C> {
129129
let id: Id = id.as_id();
130130
let mut r = self.struct_map.update(id);
131131
let stamp = &mut r.stamps[field_index];
132+
133+
if stamp.durability != Durability::LOW {
134+
runtime.report_tracked_write(stamp.durability);
135+
}
136+
132137
stamp.durability = durability;
133-
stamp.changed_at = current_revision;
138+
stamp.changed_at = runtime.current_revision();
134139
setter(&mut r.fields)
135140
}
136141

src/input/setter.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use std::marker::PhantomData;
22

33
use crate::input::{Configuration, IngredientImpl};
4-
use crate::{Durability, Revision};
4+
use crate::{Durability, Runtime};
55

66
/// Setter for a field of an input.
77
pub trait Setter: Sized {
@@ -12,7 +12,7 @@ pub trait Setter: Sized {
1212

1313
#[must_use]
1414
pub struct SetterImpl<'setter, C: Configuration, S, F> {
15-
current_revision: Revision,
15+
runtime: &'setter mut Runtime,
1616
id: C::Struct,
1717
ingredient: &'setter mut IngredientImpl<C>,
1818
durability: Durability,
@@ -27,14 +27,14 @@ where
2727
S: FnOnce(&mut C::Fields, F) -> F,
2828
{
2929
pub fn new(
30-
current_revision: Revision,
30+
runtime: &'setter mut Runtime,
3131
id: C::Struct,
3232
field_index: usize,
3333
ingredient: &'setter mut IngredientImpl<C>,
3434
setter: S,
3535
) -> Self {
3636
SetterImpl {
37-
current_revision,
37+
runtime,
3838
id,
3939
field_index,
4040
ingredient,
@@ -59,7 +59,7 @@ where
5959

6060
fn to(self, value: F) -> F {
6161
let Self {
62-
current_revision,
62+
runtime,
6363
id,
6464
ingredient,
6565
durability,
@@ -68,7 +68,7 @@ where
6868
phantom: _,
6969
} = self;
7070

71-
ingredient.set_field(current_revision, id, field_index, durability, |tuple| {
71+
ingredient.set_field(runtime, id, field_index, durability, |tuple| {
7272
setter(tuple, value)
7373
})
7474
}

src/zalsa.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -172,8 +172,14 @@ impl Zalsa {
172172
}
173173

174174
/// **NOT SEMVER STABLE**
175-
pub fn lookup_ingredient_mut(&mut self, index: IngredientIndex) -> &mut dyn Ingredient {
176-
&mut **self.ingredients_vec.get_mut(index.as_usize()).unwrap()
175+
pub fn lookup_ingredient_mut(
176+
&mut self,
177+
index: IngredientIndex,
178+
) -> (&mut dyn Ingredient, &mut Runtime) {
179+
(
180+
&mut **self.ingredients_vec.get_mut(index.as_usize()).unwrap(),
181+
&mut self.runtime,
182+
)
177183
}
178184

179185
/// **NOT SEMVER STABLE**
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
#![allow(warnings)]
2+
3+
use salsa::plumbing::HasStorage;
4+
use salsa::{Database, Durability, Setter};
5+
6+
mod common;
7+
#[salsa::input]
8+
struct MyInput {
9+
field: u32,
10+
}
11+
12+
#[salsa::tracked]
13+
fn tracked_fn(db: &dyn salsa::Database, input: MyInput) -> u32 {
14+
input.field(db) * 2
15+
}
16+
17+
#[test]
18+
fn execute() {
19+
let mut db = salsa::DatabaseImpl::default();
20+
21+
let input_high = MyInput::new(&mut db, 0);
22+
input_high
23+
.set_field(&mut db)
24+
.with_durability(Durability::HIGH)
25+
.to(2200);
26+
27+
assert_eq!(tracked_fn(&db, input_high), 4400);
28+
29+
// Changing the value should re-execute the query
30+
input_high
31+
.set_field(&mut db)
32+
.with_durability(Durability::HIGH)
33+
.to(2201);
34+
35+
assert_eq!(tracked_fn(&db, input_high), 4402);
36+
}

0 commit comments

Comments
 (0)