adjust public api from is_constant to durability

This commit is contained in:
Niko Matsakis 2019-06-25 17:43:52 -04:00
parent 880b29a640
commit 09c9bd9761
9 changed files with 56 additions and 37 deletions

View file

@ -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

View file

@ -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

View file

@ -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 {

View file

@ -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)
}

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -524,7 +524,7 @@ where
impl<DB: Database> Default for SharedState<DB> {
fn default() -> Self {
Self::with_durabilities(2)
Self::with_durabilities(Durability::LEN)
}
}

View file

@ -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