mirror of
https://github.com/salsa-rs/salsa.git
synced 2024-12-25 05:29:43 +00:00
adjust public api from is_constant
to durability
This commit is contained in:
parent
880b29a640
commit
09c9bd9761
9 changed files with 56 additions and 37 deletions
14
src/debug.rs
14
src/debug.rs
|
@ -1,6 +1,7 @@
|
|||
//! Debugging APIs: these are meant for use when unit-testing or
|
||||
//! debugging your application but aren't ordinarily needed.
|
||||
|
||||
use crate::durability::Durability;
|
||||
use crate::plumbing;
|
||||
use crate::plumbing::QueryStorageOps;
|
||||
use crate::Query;
|
||||
|
@ -17,10 +18,11 @@ pub trait DebugQueryTable {
|
|||
/// Value of this query.
|
||||
type Value;
|
||||
|
||||
/// True if salsa thinks that the value for `key` is a
|
||||
/// **constant**, meaning that it can never change, no matter what
|
||||
/// values the inputs take on from this point.
|
||||
fn is_constant(&self, key: Self::Key) -> bool;
|
||||
/// Returns a lower bound on the durability for the given key.
|
||||
/// This is typically the minimum durability of all values that
|
||||
/// the query accessed, but we may return a lower durability in
|
||||
/// some cases.
|
||||
fn durability(&self, key: Self::Key) -> Durability;
|
||||
|
||||
/// Get the (current) set of the entries in the query table.
|
||||
fn entries<C>(&self) -> C
|
||||
|
@ -56,8 +58,8 @@ where
|
|||
type Key = Q::Key;
|
||||
type Value = Q::Value;
|
||||
|
||||
fn is_constant(&self, key: Q::Key) -> bool {
|
||||
self.storage.is_constant(self.db, &key)
|
||||
fn durability(&self, key: Q::Key) -> Durability {
|
||||
self.storage.durability(self.db, &key)
|
||||
}
|
||||
|
||||
fn entries<C>(&self) -> C
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
use crate::debug::TableEntry;
|
||||
use crate::durability::Durability;
|
||||
use crate::lru::Lru;
|
||||
use crate::plumbing::CycleDetected;
|
||||
use crate::plumbing::HasQueryGroup;
|
||||
|
@ -150,8 +151,8 @@ where
|
|||
Ok(value)
|
||||
}
|
||||
|
||||
fn is_constant(&self, db: &DB, key: &Q::Key) -> bool {
|
||||
self.slot(key).is_constant(db)
|
||||
fn durability(&self, db: &DB, key: &Q::Key) -> Durability {
|
||||
self.slot(key).durability(db)
|
||||
}
|
||||
|
||||
fn entries<C>(&self, _db: &DB) -> C
|
||||
|
|
|
@ -357,12 +357,16 @@ where
|
|||
ProbeState::StaleOrAbsent(state)
|
||||
}
|
||||
|
||||
pub(super) fn is_constant(&self, db: &DB) -> bool {
|
||||
pub(super) fn durability(&self, db: &DB) -> Durability {
|
||||
match &*self.state.read() {
|
||||
QueryState::NotComputed => false,
|
||||
QueryState::NotComputed => Durability::LOW,
|
||||
QueryState::InProgress { .. } => panic!("query in progress"),
|
||||
QueryState::Memoized(memo) => {
|
||||
db.salsa_runtime().is_constant(memo.durability) && memo.is_still_constant(db)
|
||||
if memo.check_durability(db) {
|
||||
memo.durability
|
||||
} else {
|
||||
Durability::LOW
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -619,12 +623,11 @@ where
|
|||
Q: QueryFunction<DB>,
|
||||
DB: Database + HasQueryGroup<Q::Group>,
|
||||
{
|
||||
/// True if this memo should still be considered constant
|
||||
/// (presuming it ever was).
|
||||
fn is_still_constant(&self, db: &DB) -> bool {
|
||||
/// True if this memo is known not to have changed based on its durability.
|
||||
fn check_durability(&self, db: &DB) -> bool {
|
||||
let last_changed = db.salsa_runtime().last_changed_revision(self.durability);
|
||||
debug!(
|
||||
"is_still_constant(last_changed={:?} <= verified_at={:?}) = {:?}",
|
||||
"check_durability(last_changed={:?} <= verified_at={:?}) = {:?}",
|
||||
last_changed,
|
||||
self.verified_at,
|
||||
last_changed <= self.verified_at,
|
||||
|
@ -651,7 +654,7 @@ where
|
|||
self.inputs,
|
||||
);
|
||||
|
||||
if self.is_still_constant(db) {
|
||||
if self.check_durability(db) {
|
||||
return Some(self.verify_value(revision_now));
|
||||
}
|
||||
|
||||
|
@ -845,7 +848,7 @@ where
|
|||
// If we only depended on constants, and no constant has been
|
||||
// modified since then, we cannot have changed; no need to
|
||||
// trace our inputs.
|
||||
if memo.is_still_constant(db) {
|
||||
if memo.check_durability(db) {
|
||||
std::mem::drop(state);
|
||||
maybe_changed = false;
|
||||
} else {
|
||||
|
|
|
@ -19,10 +19,25 @@
|
|||
pub struct Durability(u8);
|
||||
|
||||
impl Durability {
|
||||
/// Low durability: things that change frequently.
|
||||
///
|
||||
/// Example: part of the crate being edited
|
||||
pub const LOW: Durability = Durability(0);
|
||||
|
||||
/// Medium durability: things that change sometimes, but rarely.
|
||||
///
|
||||
/// Example: a Cargo.toml file
|
||||
pub const MEDIUM: Durability = Durability(1);
|
||||
|
||||
/// High durability: things that are not expected to change under
|
||||
/// common usage.
|
||||
///
|
||||
/// Example: the standard library or something from crates.io
|
||||
pub const HIGH: Durability = Durability(2);
|
||||
|
||||
/// Number of durability levels.
|
||||
pub(crate) const LEN: usize = 3;
|
||||
|
||||
pub(crate) fn new(v: usize) -> Durability {
|
||||
Durability(v as u8)
|
||||
}
|
||||
|
|
|
@ -145,13 +145,10 @@ where
|
|||
Ok(value)
|
||||
}
|
||||
|
||||
fn is_constant(&self, db: &DB, key: &Q::Key) -> bool {
|
||||
fn durability(&self, _db: &DB, key: &Q::Key) -> Durability {
|
||||
self.slot(key)
|
||||
.map(|slot| {
|
||||
db.salsa_runtime()
|
||||
.is_constant(slot.stamped_value.read().durability)
|
||||
})
|
||||
.unwrap_or(false)
|
||||
.map(|slot| slot.stamped_value.read().durability)
|
||||
.unwrap_or(Durability::LOW)
|
||||
}
|
||||
|
||||
fn entries<C>(&self, _db: &DB) -> C
|
||||
|
|
|
@ -328,8 +328,8 @@ where
|
|||
Ok(<Q::Value>::from_intern_id(index))
|
||||
}
|
||||
|
||||
fn is_constant(&self, _db: &DB, _key: &Q::Key) -> bool {
|
||||
false
|
||||
fn durability(&self, _db: &DB, _key: &Q::Key) -> Durability {
|
||||
Durability::LOW
|
||||
}
|
||||
|
||||
fn entries<C>(&self, _db: &DB) -> C
|
||||
|
@ -429,8 +429,8 @@ where
|
|||
Ok(value)
|
||||
}
|
||||
|
||||
fn is_constant(&self, _db: &DB, _key: &Q::Key) -> bool {
|
||||
false
|
||||
fn durability(&self, _db: &DB, _key: &Q::Key) -> Durability {
|
||||
Durability::LOW
|
||||
}
|
||||
|
||||
fn entries<C>(&self, db: &DB) -> C
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#![allow(missing_docs)]
|
||||
|
||||
use crate::debug::TableEntry;
|
||||
use crate::durability::Durability;
|
||||
use crate::Database;
|
||||
use crate::Query;
|
||||
use crate::QueryTable;
|
||||
|
@ -147,8 +148,8 @@ where
|
|||
/// itself.
|
||||
fn try_fetch(&self, db: &DB, key: &Q::Key) -> Result<Q::Value, CycleDetected>;
|
||||
|
||||
/// Check if `key` is (currently) believed to be a constant.
|
||||
fn is_constant(&self, db: &DB, key: &Q::Key) -> bool;
|
||||
/// Returns the durability associated with a given key.
|
||||
fn durability(&self, db: &DB, key: &Q::Key) -> Durability;
|
||||
|
||||
/// Get the (current) set of the entries in the query storage
|
||||
fn entries<C>(&self, db: &DB) -> C
|
||||
|
|
|
@ -524,7 +524,7 @@ where
|
|||
|
||||
impl<DB: Database> Default for SharedState<DB> {
|
||||
fn default() -> Self {
|
||||
Self::with_durabilities(2)
|
||||
Self::with_durabilities(Durability::LEN)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use crate::implementation::{TestContext, TestContextImpl};
|
||||
use salsa::debug::DebugQueryTable;
|
||||
use salsa::Database;
|
||||
use salsa::{Database, Durability};
|
||||
|
||||
#[salsa::query_group(Constants)]
|
||||
pub(crate) trait ConstantsDatabase: TestContext {
|
||||
|
@ -69,7 +69,7 @@ fn not_constant() {
|
|||
db.set_input('a', 22);
|
||||
db.set_input('b', 44);
|
||||
assert_eq!(db.add('a', 'b'), 66);
|
||||
assert!(!db.query(AddQuery).is_constant(('a', 'b')));
|
||||
assert_eq!(Durability::LOW, db.query(AddQuery).durability(('a', 'b')));
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -79,7 +79,7 @@ fn durability() {
|
|||
db.set_constant_input('a', 22);
|
||||
db.set_constant_input('b', 44);
|
||||
assert_eq!(db.add('a', 'b'), 66);
|
||||
assert!(db.query(AddQuery).is_constant(('a', 'b')));
|
||||
assert_eq!(Durability::HIGH, db.query(AddQuery).durability(('a', 'b')));
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -89,7 +89,7 @@ fn mixed_constant() {
|
|||
db.set_constant_input('a', 22);
|
||||
db.set_input('b', 44);
|
||||
assert_eq!(db.add('a', 'b'), 66);
|
||||
assert!(!db.query(AddQuery).is_constant(('a', 'b')));
|
||||
assert_eq!(Durability::LOW, db.query(AddQuery).durability(('a', 'b')));
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -99,15 +99,15 @@ fn becomes_constant_with_change() {
|
|||
db.set_input('a', 22);
|
||||
db.set_input('b', 44);
|
||||
assert_eq!(db.add('a', 'b'), 66);
|
||||
assert!(!db.query(AddQuery).is_constant(('a', 'b')));
|
||||
assert_eq!(Durability::LOW, db.query(AddQuery).durability(('a', 'b')));
|
||||
|
||||
db.set_constant_input('a', 23);
|
||||
assert_eq!(db.add('a', 'b'), 67);
|
||||
assert!(!db.query(AddQuery).is_constant(('a', 'b')));
|
||||
assert_eq!(Durability::LOW, db.query(AddQuery).durability(('a', 'b')));
|
||||
|
||||
db.set_constant_input('b', 45);
|
||||
assert_eq!(db.add('a', 'b'), 68);
|
||||
assert!(db.query(AddQuery).is_constant(('a', 'b')));
|
||||
assert_eq!(Durability::HIGH, db.query(AddQuery).durability(('a', 'b')));
|
||||
}
|
||||
|
||||
// Test a subtle case in which an input changes from constant to
|
||||
|
|
Loading…
Reference in a new issue