mirror of
https://github.com/salsa-rs/salsa.git
synced 2025-01-13 00:40:22 +00:00
Merge branch 'master' into append-only-vec
This commit is contained in:
commit
9964c8e834
14 changed files with 75 additions and 32 deletions
2
.github/workflows/test.yml
vendored
2
.github/workflows/test.yml
vendored
|
@ -51,7 +51,7 @@ jobs:
|
|||
- name: Format
|
||||
run: cargo fmt -- --check
|
||||
- name: Clippy
|
||||
run: cargo clippy --workspace --all-features --all-targets
|
||||
run: cargo clippy --workspace --all-features --all-targets -- -D warnings
|
||||
- name: Test
|
||||
run: cargo test --workspace --all-features --all-targets
|
||||
- name: Test docs
|
||||
|
|
|
@ -9,7 +9,6 @@ description = "A generic framework for on-demand, incrementalized computation (e
|
|||
|
||||
[dependencies]
|
||||
arc-swap = "1"
|
||||
boomphf = "0.6"
|
||||
crossbeam = "0.8"
|
||||
dashmap = "6"
|
||||
hashlink = "0.9"
|
||||
|
@ -32,7 +31,7 @@ eyre = "0.6.8"
|
|||
notify-debouncer-mini = "0.4.1"
|
||||
ordered-float = "4.2.1"
|
||||
rustversion = "1.0"
|
||||
test-log = "0.2.11"
|
||||
test-log = { version ="0.2.11", features = ["trace"] }
|
||||
trybuild = "1.0"
|
||||
|
||||
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -225,6 +225,7 @@ macro_rules! setup_tracked_fn {
|
|||
}
|
||||
}
|
||||
|
||||
#[allow(non_local_definitions)]
|
||||
impl $fn_name {
|
||||
pub fn accumulated<$db_lt, A: salsa::Accumulator>(
|
||||
$db: &$db_lt dyn $Db,
|
||||
|
|
|
@ -110,7 +110,7 @@ impl ActiveQuery {
|
|||
}
|
||||
|
||||
/// Adds any dependencies from `other` into `self`.
|
||||
/// Used during cycle recovery, see [`Runtime::create_cycle_error`].
|
||||
/// Used during cycle recovery, see [`Runtime::unblock_cycle_and_maybe_throw`].
|
||||
pub(super) fn add_from(&mut self, other: &ActiveQuery) {
|
||||
self.changed_at = self.changed_at.max(other.changed_at);
|
||||
self.durability = self.durability.min(other.durability);
|
||||
|
@ -120,7 +120,7 @@ impl ActiveQuery {
|
|||
}
|
||||
|
||||
/// Removes the participants in `cycle` from my dependencies.
|
||||
/// Used during cycle recovery, see [`Runtime::create_cycle_error`].
|
||||
/// Used during cycle recovery, see [`Runtime::unblock_cycle_and_maybe_throw`].
|
||||
pub(super) fn remove_cycle_participants(&mut self, cycle: &Cycle) {
|
||||
for p in cycle.participant_keys() {
|
||||
let p: DependencyIndex = p.into();
|
||||
|
@ -129,7 +129,7 @@ impl ActiveQuery {
|
|||
}
|
||||
|
||||
/// Copy the changed-at, durability, and dependencies from `cycle_query`.
|
||||
/// Used during cycle recovery, see [`Runtime::create_cycle_error`].
|
||||
/// Used during cycle recovery, see [`Runtime::unblock_cycle_and_maybe_throw`].
|
||||
pub(crate) fn take_inputs_from(&mut self, cycle_query: &ActiveQuery) {
|
||||
self.changed_at = cycle_query.changed_at;
|
||||
self.durability = cycle_query.durability;
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
use std::fmt::Debug;
|
||||
use std::ops::{Deref, DerefMut};
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
pub struct Array<T, const N: usize> {
|
||||
data: [T; N],
|
||||
}
|
||||
|
|
|
@ -94,17 +94,15 @@ impl std::fmt::Debug for Cycle {
|
|||
pub enum CycleRecoveryStrategy {
|
||||
/// Cannot recover from cycles: panic.
|
||||
///
|
||||
/// This is the default. It is also what happens if a cycle
|
||||
/// occurs and the queries involved have different recovery
|
||||
/// strategies.
|
||||
/// This is the default.
|
||||
///
|
||||
/// In the case of a failure due to a cycle, the panic
|
||||
/// value will be XXX (FIXME).
|
||||
/// value will be the `Cycle`.
|
||||
Panic,
|
||||
|
||||
/// Recovers from cycles by storing a sentinel value.
|
||||
///
|
||||
/// This value is computed by the `QueryFunction::cycle_fallback`
|
||||
/// This value is computed by the query's `recovery_fn`
|
||||
/// function.
|
||||
Fallback,
|
||||
}
|
||||
|
|
|
@ -65,7 +65,7 @@ pub trait Configuration: Any {
|
|||
/// This invokes the function the user wrote.
|
||||
fn execute<'db>(db: &'db Self::DbView, input: Self::Input<'db>) -> Self::Output<'db>;
|
||||
|
||||
/// If the cycle strategy is `Recover`, then invoked when `key` is a participant
|
||||
/// If the cycle strategy is `Fallback`, then invoked when `key` is a participant
|
||||
/// in a cycle to find out what value it should have.
|
||||
///
|
||||
/// This invokes the recovery function given by the user.
|
||||
|
|
13
src/input.rs
13
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 {
|
||||
|
@ -35,7 +35,7 @@ pub trait Configuration: Any {
|
|||
type Fields: Send + Sync;
|
||||
|
||||
/// A array of [`StampedValue<()>`](`StampedValue`) tuples, one per each of the value fields.
|
||||
type Stamps: Send + Sync + DerefMut<Target = [Stamp]>;
|
||||
type Stamps: Send + Sync + fmt::Debug + DerefMut<Target = [Stamp]>;
|
||||
}
|
||||
|
||||
pub struct JarImpl<C: Configuration> {
|
||||
|
@ -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
|
@ -171,8 +171,14 @@ impl Zalsa {
|
|||
}
|
||||
|
||||
/// **NOT SEMVER STABLE**
|
||||
pub fn lookup_ingredient_mut(&mut self, index: IngredientIndex) -> &mut dyn Ingredient {
|
||||
&mut **(&mut self.ingredients_vec[index.as_usize()])
|
||||
pub fn lookup_ingredient_mut(
|
||||
&mut self,
|
||||
index: IngredientIndex,
|
||||
) -> (&mut dyn Ingredient, &mut Runtime) {
|
||||
(
|
||||
&mut **(&mut self.ingredients_vec[index.as_usize()]),
|
||||
&mut self.runtime,
|
||||
)
|
||||
}
|
||||
|
||||
/// **NOT SEMVER STABLE**
|
||||
|
|
|
@ -109,7 +109,7 @@ impl ZalsaLocal {
|
|||
changed_at: Revision,
|
||||
) {
|
||||
debug!(
|
||||
"report_query_read_and_unwind_if_cycle_resulted(input={:?}, durability={:?}, changed_at={:?})",
|
||||
"report_tracked_read(input={:?}, durability={:?}, changed_at={:?})",
|
||||
input, durability, changed_at
|
||||
);
|
||||
self.with_query_stack(|stack| {
|
||||
|
|
|
@ -49,9 +49,6 @@ use salsa::Durability;
|
|||
// | Cross | Fallback | N/A | Tracked | both | parallel/parallel_cycle_mid_recover.rs |
|
||||
// | Cross | Fallback | N/A | Tracked | both | parallel/parallel_cycle_all_recover.rs |
|
||||
|
||||
// TODO: The following test is not yet ported.
|
||||
// | Intra | Fallback | Old | Tracked | direct | cycle_disappears_durability |
|
||||
|
||||
#[derive(PartialEq, Eq, Hash, Clone, Debug)]
|
||||
struct Error {
|
||||
cycle: Vec<String>,
|
||||
|
|
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