mirror of
https://github.com/salsa-rs/salsa.git
synced 2025-02-02 09:46:06 +00:00
remove a lot of ()
keys
This commit is contained in:
parent
2410a2242c
commit
120ba00f33
9 changed files with 98 additions and 97 deletions
|
@ -9,12 +9,12 @@ salsa::query_group! {
|
|||
}
|
||||
|
||||
/// Get the list of all classes
|
||||
fn all_classes(key: ()) -> Arc<Vec<DefId>> {
|
||||
fn all_classes() -> Arc<Vec<DefId>> {
|
||||
type AllClasses;
|
||||
}
|
||||
|
||||
/// Get the list of all fields
|
||||
fn all_fields(key: ()) -> Arc<Vec<DefId>> {
|
||||
fn all_fields() -> Arc<Vec<DefId>> {
|
||||
type AllFields;
|
||||
}
|
||||
}
|
||||
|
@ -23,7 +23,7 @@ salsa::query_group! {
|
|||
#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
|
||||
pub struct DefId(usize);
|
||||
|
||||
fn all_classes(_: &impl ClassTableDatabase, (): ()) -> Arc<Vec<DefId>> {
|
||||
fn all_classes(_: &impl ClassTableDatabase) -> Arc<Vec<DefId>> {
|
||||
Arc::new(vec![DefId(0), DefId(10)]) // dummy impl
|
||||
}
|
||||
|
||||
|
@ -31,14 +31,15 @@ fn fields(_: &impl ClassTableDatabase, class: DefId) -> Arc<Vec<DefId>> {
|
|||
Arc::new(vec![DefId(class.0 + 1), DefId(class.0 + 2)]) // dummy impl
|
||||
}
|
||||
|
||||
fn all_fields(db: &impl ClassTableDatabase, (): ()) -> Arc<Vec<DefId>> {
|
||||
fn all_fields(db: &impl ClassTableDatabase) -> Arc<Vec<DefId>> {
|
||||
Arc::new(
|
||||
db.all_classes(())
|
||||
db.all_classes()
|
||||
.iter()
|
||||
.cloned()
|
||||
.flat_map(|def_id| {
|
||||
let fields = db.fields(def_id);
|
||||
(0..fields.len()).map(move |i| fields[i])
|
||||
}).collect(),
|
||||
})
|
||||
.collect(),
|
||||
)
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@ use self::implementation::DatabaseImpl;
|
|||
#[test]
|
||||
fn test() {
|
||||
let query = DatabaseImpl::default();
|
||||
let all_def_ids = query.all_fields(());
|
||||
let all_def_ids = query.all_fields();
|
||||
assert_eq!(
|
||||
format!("{:?}", all_def_ids),
|
||||
"[DefId(1), DefId(2), DefId(11), DefId(12)]"
|
||||
|
@ -17,7 +17,7 @@ fn test() {
|
|||
|
||||
fn main() {
|
||||
let query = DatabaseImpl::default();
|
||||
for f in query.all_fields(()).iter() {
|
||||
for f in query.all_fields().iter() {
|
||||
println!("{:?}", f);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,49 +23,49 @@ salsa::database_storage! {
|
|||
salsa::query_group! {
|
||||
trait Database: salsa::Database {
|
||||
// `a` and `b` depend on each other and form a cycle
|
||||
fn memoized_a(key: ()) -> () {
|
||||
fn memoized_a() -> () {
|
||||
type MemoizedA;
|
||||
}
|
||||
fn memoized_b(key: ()) -> () {
|
||||
fn memoized_b() -> () {
|
||||
type MemoizedB;
|
||||
}
|
||||
fn volatile_a(key: ()) -> () {
|
||||
fn volatile_a() -> () {
|
||||
type VolatileA;
|
||||
storage volatile;
|
||||
}
|
||||
fn volatile_b(key: ()) -> () {
|
||||
fn volatile_b() -> () {
|
||||
type VolatileB;
|
||||
storage volatile;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn memoized_a(db: &impl Database, (): ()) -> () {
|
||||
db.memoized_b(())
|
||||
fn memoized_a(db: &impl Database) -> () {
|
||||
db.memoized_b()
|
||||
}
|
||||
|
||||
fn memoized_b(db: &impl Database, (): ()) -> () {
|
||||
db.memoized_a(())
|
||||
fn memoized_b(db: &impl Database) -> () {
|
||||
db.memoized_a()
|
||||
}
|
||||
|
||||
fn volatile_a(db: &impl Database, (): ()) -> () {
|
||||
db.volatile_b(())
|
||||
fn volatile_a(db: &impl Database) -> () {
|
||||
db.volatile_b()
|
||||
}
|
||||
|
||||
fn volatile_b(db: &impl Database, (): ()) -> () {
|
||||
db.volatile_a(())
|
||||
fn volatile_b(db: &impl Database) -> () {
|
||||
db.volatile_a()
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic(expected = "cycle detected")]
|
||||
fn cycle_memoized() {
|
||||
let query = DatabaseImpl::default();
|
||||
query.memoized_a(());
|
||||
query.memoized_a();
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic(expected = "cycle detected")]
|
||||
fn cycle_volatile() {
|
||||
let query = DatabaseImpl::default();
|
||||
query.volatile_a(());
|
||||
query.volatile_a();
|
||||
}
|
||||
|
|
|
@ -3,40 +3,40 @@ use salsa::Database;
|
|||
|
||||
salsa::query_group! {
|
||||
pub(crate) trait MemoizedDepInputsContext: TestContext {
|
||||
fn dep_memoized2(key: ()) -> usize {
|
||||
fn dep_memoized2() -> usize {
|
||||
type Memoized2;
|
||||
}
|
||||
fn dep_memoized1(key: ()) -> usize {
|
||||
fn dep_memoized1() -> usize {
|
||||
type Memoized1;
|
||||
}
|
||||
fn dep_derived1(key: ()) -> usize {
|
||||
fn dep_derived1() -> usize {
|
||||
type Derived1;
|
||||
storage dependencies;
|
||||
}
|
||||
fn dep_input1(key: ()) -> usize {
|
||||
fn dep_input1() -> usize {
|
||||
type Input1;
|
||||
storage input;
|
||||
}
|
||||
fn dep_input2(key: ()) -> usize {
|
||||
fn dep_input2() -> usize {
|
||||
type Input2;
|
||||
storage input;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn dep_memoized2(db: &impl MemoizedDepInputsContext, (): ()) -> usize {
|
||||
fn dep_memoized2(db: &impl MemoizedDepInputsContext) -> usize {
|
||||
db.log().add("Memoized2 invoked");
|
||||
db.dep_memoized1(())
|
||||
db.dep_memoized1()
|
||||
}
|
||||
|
||||
fn dep_memoized1(db: &impl MemoizedDepInputsContext, (): ()) -> usize {
|
||||
fn dep_memoized1(db: &impl MemoizedDepInputsContext) -> usize {
|
||||
db.log().add("Memoized1 invoked");
|
||||
db.dep_derived1(()) * 2
|
||||
db.dep_derived1() * 2
|
||||
}
|
||||
|
||||
fn dep_derived1(db: &impl MemoizedDepInputsContext, (): ()) -> usize {
|
||||
fn dep_derived1(db: &impl MemoizedDepInputsContext) -> usize {
|
||||
db.log().add("Derived1 invoked");
|
||||
db.dep_input1(()) / 2
|
||||
db.dep_input1() / 2
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -44,7 +44,7 @@ fn revalidate() {
|
|||
let db = &TestContextImpl::default();
|
||||
|
||||
// Initial run starts from Memoized2:
|
||||
let v = db.dep_memoized2(());
|
||||
let v = db.dep_memoized2();
|
||||
assert_eq!(v, 0);
|
||||
db.assert_log(&["Memoized2 invoked", "Memoized1 invoked", "Derived1 invoked"]);
|
||||
|
||||
|
@ -52,19 +52,19 @@ fn revalidate() {
|
|||
// running Memoized2. Note that we don't try to validate
|
||||
// Derived1, so it is invoked by Memoized1.
|
||||
db.query(Input1).set((), 44);
|
||||
let v = db.dep_memoized2(());
|
||||
let v = db.dep_memoized2();
|
||||
assert_eq!(v, 44);
|
||||
db.assert_log(&["Memoized1 invoked", "Derived1 invoked", "Memoized2 invoked"]);
|
||||
|
||||
// Here validation of Memoized1 succeeds so Memoized2 never runs.
|
||||
db.query(Input1).set((), 45);
|
||||
let v = db.dep_memoized2(());
|
||||
let v = db.dep_memoized2();
|
||||
assert_eq!(v, 44);
|
||||
db.assert_log(&["Memoized1 invoked", "Derived1 invoked"]);
|
||||
|
||||
// Here, a change to input2 doesn't affect us, so nothing runs.
|
||||
db.query(Input2).set((), 45);
|
||||
let v = db.dep_memoized2(());
|
||||
let v = db.dep_memoized2();
|
||||
assert_eq!(v, 44);
|
||||
db.assert_log(&[]);
|
||||
}
|
||||
|
|
|
@ -3,45 +3,45 @@ use salsa::Database;
|
|||
|
||||
salsa::query_group! {
|
||||
pub(crate) trait MemoizedInputsContext: TestContext {
|
||||
fn max(key: ()) -> usize {
|
||||
fn max() -> usize {
|
||||
type Max;
|
||||
}
|
||||
fn input1(key: ()) -> usize {
|
||||
fn input1() -> usize {
|
||||
type Input1;
|
||||
storage input;
|
||||
}
|
||||
fn input2(key: ()) -> usize {
|
||||
fn input2() -> usize {
|
||||
type Input2;
|
||||
storage input;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn max(db: &impl MemoizedInputsContext, (): ()) -> usize {
|
||||
fn max(db: &impl MemoizedInputsContext) -> usize {
|
||||
db.log().add("Max invoked");
|
||||
std::cmp::max(db.input1(()), db.input2(()))
|
||||
std::cmp::max(db.input1(), db.input2())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn revalidate() {
|
||||
let db = &TestContextImpl::default();
|
||||
|
||||
let v = db.max(());
|
||||
let v = db.max();
|
||||
assert_eq!(v, 0);
|
||||
db.assert_log(&["Max invoked"]);
|
||||
|
||||
let v = db.max(());
|
||||
let v = db.max();
|
||||
assert_eq!(v, 0);
|
||||
db.assert_log(&[]);
|
||||
|
||||
db.query(Input1).set((), 44);
|
||||
db.assert_log(&[]);
|
||||
|
||||
let v = db.max(());
|
||||
let v = db.max();
|
||||
assert_eq!(v, 44);
|
||||
db.assert_log(&["Max invoked"]);
|
||||
|
||||
let v = db.max(());
|
||||
let v = db.max();
|
||||
assert_eq!(v, 44);
|
||||
db.assert_log(&[]);
|
||||
|
||||
|
@ -52,11 +52,11 @@ fn revalidate() {
|
|||
db.query(Input1).set((), 64);
|
||||
db.assert_log(&[]);
|
||||
|
||||
let v = db.max(());
|
||||
let v = db.max();
|
||||
assert_eq!(v, 66);
|
||||
db.assert_log(&["Max invoked"]);
|
||||
|
||||
let v = db.max(());
|
||||
let v = db.max();
|
||||
assert_eq!(v, 66);
|
||||
db.assert_log(&[]);
|
||||
}
|
||||
|
@ -68,12 +68,12 @@ fn set_after_no_change() {
|
|||
let db = &TestContextImpl::default();
|
||||
|
||||
db.query(Input1).set((), 44);
|
||||
let v = db.max(());
|
||||
let v = db.max();
|
||||
assert_eq!(v, 44);
|
||||
db.assert_log(&["Max invoked"]);
|
||||
|
||||
db.query(Input1).set((), 44);
|
||||
let v = db.max(());
|
||||
let v = db.max();
|
||||
assert_eq!(v, 44);
|
||||
db.assert_log(&[]);
|
||||
}
|
||||
|
|
|
@ -5,31 +5,31 @@ salsa::query_group! {
|
|||
pub(crate) trait MemoizedVolatileContext: TestContext {
|
||||
// Queries for testing a "volatile" value wrapped by
|
||||
// memoization.
|
||||
fn memoized2(key: ()) -> usize {
|
||||
fn memoized2() -> usize {
|
||||
type Memoized2;
|
||||
}
|
||||
fn memoized1(key: ()) -> usize {
|
||||
fn memoized1() -> usize {
|
||||
type Memoized1;
|
||||
}
|
||||
fn volatile(key: ()) -> usize {
|
||||
fn volatile() -> usize {
|
||||
type Volatile;
|
||||
storage volatile;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn memoized2(db: &impl MemoizedVolatileContext, (): ()) -> usize {
|
||||
fn memoized2(db: &impl MemoizedVolatileContext) -> usize {
|
||||
db.log().add("Memoized2 invoked");
|
||||
db.memoized1(())
|
||||
db.memoized1()
|
||||
}
|
||||
|
||||
fn memoized1(db: &impl MemoizedVolatileContext, (): ()) -> usize {
|
||||
fn memoized1(db: &impl MemoizedVolatileContext) -> usize {
|
||||
db.log().add("Memoized1 invoked");
|
||||
let v = db.volatile(());
|
||||
let v = db.volatile();
|
||||
v / 2
|
||||
}
|
||||
|
||||
fn volatile(db: &impl MemoizedVolatileContext, (): ()) -> usize {
|
||||
fn volatile(db: &impl MemoizedVolatileContext) -> usize {
|
||||
db.log().add("Volatile invoked");
|
||||
db.clock().increment()
|
||||
}
|
||||
|
@ -40,8 +40,8 @@ fn volatile_x2() {
|
|||
|
||||
// Invoking volatile twice doesn't execute twice, because volatile
|
||||
// queries are memoized by default.
|
||||
query.volatile(());
|
||||
query.volatile(());
|
||||
query.volatile();
|
||||
query.volatile();
|
||||
query.assert_log(&["Volatile invoked"]);
|
||||
}
|
||||
|
||||
|
@ -57,20 +57,20 @@ fn volatile_x2() {
|
|||
fn revalidate() {
|
||||
let query = TestContextImpl::default();
|
||||
|
||||
query.memoized2(());
|
||||
query.memoized2();
|
||||
query.assert_log(&["Memoized2 invoked", "Memoized1 invoked", "Volatile invoked"]);
|
||||
|
||||
query.memoized2(());
|
||||
query.memoized2();
|
||||
query.assert_log(&[]);
|
||||
|
||||
// Second generation: volatile will change (to 1) but memoized1
|
||||
// will not (still 0, as 1/2 = 0)
|
||||
query.salsa_runtime().next_revision();
|
||||
|
||||
query.memoized2(());
|
||||
query.memoized2();
|
||||
query.assert_log(&["Volatile invoked", "Memoized1 invoked"]);
|
||||
|
||||
query.memoized2(());
|
||||
query.memoized2();
|
||||
query.assert_log(&[]);
|
||||
|
||||
// Third generation: volatile will change (to 2) and memoized1
|
||||
|
@ -78,9 +78,9 @@ fn revalidate() {
|
|||
// changed, we now invoke Memoized2.
|
||||
query.salsa_runtime().next_revision();
|
||||
|
||||
query.memoized2(());
|
||||
query.memoized2();
|
||||
query.assert_log(&["Volatile invoked", "Memoized1 invoked", "Memoized2 invoked"]);
|
||||
|
||||
query.memoized2(());
|
||||
query.memoized2();
|
||||
query.assert_log(&[]);
|
||||
}
|
||||
|
|
|
@ -2,29 +2,29 @@ use salsa::Database;
|
|||
|
||||
salsa::query_group! {
|
||||
trait HelloWorldDatabase: salsa::Database {
|
||||
fn input(key: ()) -> String {
|
||||
fn input() -> String {
|
||||
type Input;
|
||||
storage input;
|
||||
}
|
||||
|
||||
fn length(key: ()) -> usize {
|
||||
fn length() -> usize {
|
||||
type Length;
|
||||
}
|
||||
|
||||
fn double_length(key: ()) -> usize {
|
||||
fn double_length() -> usize {
|
||||
type DoubleLength;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn length(db: &impl HelloWorldDatabase, (): ()) -> usize {
|
||||
let l = db.input(()).len();
|
||||
fn length(db: &impl HelloWorldDatabase) -> usize {
|
||||
let l = db.input().len();
|
||||
assert!(l > 0); // not meant to be invoked with no input
|
||||
l
|
||||
}
|
||||
|
||||
fn double_length(db: &impl HelloWorldDatabase, (): ()) -> usize {
|
||||
db.length(()) * 2
|
||||
fn double_length(db: &impl HelloWorldDatabase) -> usize {
|
||||
db.length() * 2
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
|
@ -52,35 +52,35 @@ salsa::database_storage! {
|
|||
fn normal() {
|
||||
let db = DatabaseStruct::default();
|
||||
db.query(Input).set((), format!("Hello, world"));
|
||||
assert_eq!(db.double_length(()), 24);
|
||||
assert_eq!(db.double_length(), 24);
|
||||
db.query(Input).set((), format!("Hello, world!"));
|
||||
assert_eq!(db.double_length(()), 26);
|
||||
assert_eq!(db.double_length(), 26);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn use_without_set() {
|
||||
let db = DatabaseStruct::default();
|
||||
db.double_length(());
|
||||
db.double_length();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn using_set_unchecked_on_input() {
|
||||
let db = DatabaseStruct::default();
|
||||
db.query(Input).set_unchecked((), format!("Hello, world"));
|
||||
assert_eq!(db.double_length(()), 24);
|
||||
assert_eq!(db.double_length(), 24);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn using_set_unchecked_on_input_after() {
|
||||
let db = DatabaseStruct::default();
|
||||
db.query(Input).set((), format!("Hello, world"));
|
||||
assert_eq!(db.double_length(()), 24);
|
||||
assert_eq!(db.double_length(), 24);
|
||||
|
||||
// If we use `set_unchecked`, we don't notice that `double_length`
|
||||
// is out of date. Oh well, don't do that.
|
||||
db.query(Input).set_unchecked((), format!("Hello, world!"));
|
||||
assert_eq!(db.double_length(()), 24);
|
||||
assert_eq!(db.double_length(), 24);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -91,5 +91,5 @@ fn using_set_unchecked() {
|
|||
// demonstrating that the code never runs.
|
||||
db.query(Length).set_unchecked((), 24);
|
||||
|
||||
assert_eq!(db.double_length(()), 48);
|
||||
assert_eq!(db.double_length(), 48);
|
||||
}
|
||||
|
|
|
@ -4,10 +4,10 @@ pub(crate) trait Counter: salsa::Database {
|
|||
|
||||
salsa::query_group! {
|
||||
pub(crate) trait Database: Counter {
|
||||
fn memoized(key: ()) -> usize {
|
||||
fn memoized() -> usize {
|
||||
type Memoized;
|
||||
}
|
||||
fn volatile(key: ()) -> usize {
|
||||
fn volatile() -> usize {
|
||||
type Volatile;
|
||||
storage volatile;
|
||||
}
|
||||
|
@ -16,12 +16,12 @@ salsa::query_group! {
|
|||
|
||||
/// Because this query is memoized, we only increment the counter
|
||||
/// the first time it is invoked.
|
||||
fn memoized(db: &impl Database, (): ()) -> usize {
|
||||
db.volatile(())
|
||||
fn memoized(db: &impl Database) -> usize {
|
||||
db.volatile()
|
||||
}
|
||||
|
||||
/// Because this query is volatile, each time it is invoked,
|
||||
/// we will increment the counter.
|
||||
fn volatile(db: &impl Database, (): ()) -> usize {
|
||||
fn volatile(db: &impl Database) -> usize {
|
||||
db.increment()
|
||||
}
|
||||
|
|
|
@ -7,22 +7,22 @@ use salsa::Database as _Database;
|
|||
#[test]
|
||||
fn memoized_twice() {
|
||||
let db = DatabaseImpl::default();
|
||||
let v1 = db.memoized(());
|
||||
let v2 = db.memoized(());
|
||||
let v1 = db.memoized();
|
||||
let v2 = db.memoized();
|
||||
assert_eq!(v1, v2);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn volatile_twice() {
|
||||
let db = DatabaseImpl::default();
|
||||
let v1 = db.volatile(());
|
||||
let v2 = db.volatile(()); // volatiles are cached, so 2nd read returns the same
|
||||
let v1 = db.volatile();
|
||||
let v2 = db.volatile(); // volatiles are cached, so 2nd read returns the same
|
||||
assert_eq!(v1, v2);
|
||||
|
||||
db.salsa_runtime().next_revision(); // clears volatile caches
|
||||
|
||||
let v3 = db.volatile(()); // will re-increment the counter
|
||||
let v4 = db.volatile(()); // second call will be cached
|
||||
let v3 = db.volatile(); // will re-increment the counter
|
||||
let v4 = db.volatile(); // second call will be cached
|
||||
assert_eq!(v1 + 1, v3);
|
||||
assert_eq!(v3, v4);
|
||||
}
|
||||
|
@ -30,10 +30,10 @@ fn volatile_twice() {
|
|||
#[test]
|
||||
fn intermingled() {
|
||||
let db = DatabaseImpl::default();
|
||||
let v1 = db.volatile(());
|
||||
let v2 = db.memoized(());
|
||||
let v3 = db.volatile(()); // cached
|
||||
let v4 = db.memoized(()); // cached
|
||||
let v1 = db.volatile();
|
||||
let v2 = db.memoized();
|
||||
let v3 = db.volatile(); // cached
|
||||
let v4 = db.memoized(); // cached
|
||||
|
||||
assert_eq!(v1, v2);
|
||||
assert_eq!(v1, v3);
|
||||
|
@ -41,8 +41,8 @@ fn intermingled() {
|
|||
|
||||
db.salsa_runtime().next_revision(); // clears volatile caches
|
||||
|
||||
let v5 = db.memoized(()); // re-executes volatile, caches new result
|
||||
let v6 = db.memoized(()); // re-use cached result
|
||||
let v5 = db.memoized(); // re-executes volatile, caches new result
|
||||
let v6 = db.memoized(); // re-use cached result
|
||||
assert_eq!(v4 + 1, v5);
|
||||
assert_eq!(v5, v6);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue