salsa/tests/incremental/memoized_volatile.rs

85 lines
2.4 KiB
Rust
Raw Normal View History

use crate::implementation::{TestContext, TestContextImpl};
2018-10-05 08:54:51 +00:00
use salsa::Database;
salsa::query_group! {
2018-10-09 19:34:30 +00:00
pub(crate) trait MemoizedVolatileContext: TestContext {
// Queries for testing a "volatile" value wrapped by
// memoization.
2018-10-19 01:26:48 +00:00
fn memoized2() -> usize {
type Memoized2;
}
2018-10-19 01:26:48 +00:00
fn memoized1() -> usize {
type Memoized1;
}
2018-10-19 01:26:48 +00:00
fn volatile() -> usize {
type Volatile;
storage volatile;
}
}
}
2018-10-19 01:26:48 +00:00
fn memoized2(db: &impl MemoizedVolatileContext) -> usize {
2018-10-05 14:30:17 +00:00
db.log().add("Memoized2 invoked");
2018-10-19 01:26:48 +00:00
db.memoized1()
}
2018-10-19 01:26:48 +00:00
fn memoized1(db: &impl MemoizedVolatileContext) -> usize {
2018-10-05 14:30:17 +00:00
db.log().add("Memoized1 invoked");
2018-10-19 01:26:48 +00:00
let v = db.volatile();
2018-10-05 14:30:17 +00:00
v / 2
}
2018-10-19 01:26:48 +00:00
fn volatile(db: &impl MemoizedVolatileContext) -> usize {
2018-10-05 14:30:17 +00:00
db.log().add("Volatile invoked");
db.clock().increment()
}
#[test]
fn volatile_x2() {
let query = TestContextImpl::default();
// Invoking volatile twice doesn't execute twice, because volatile
// queries are memoized by default.
2018-10-19 01:26:48 +00:00
query.volatile();
query.volatile();
query.assert_log(&["Volatile invoked"]);
}
2018-09-30 11:32:24 +00:00
/// Test that:
///
/// - On the first run of R0, we recompute everything.
/// - On the second run of R1, we recompute nothing.
/// - On the first run of R1, we recompute Memoized1 but not Memoized2 (since Memoized1 result
/// did not change).
/// - On the second run of R1, we recompute nothing.
/// - On the first run of R2, we recompute everything (since Memoized1 result *did* change).
#[test]
2018-09-30 11:32:24 +00:00
fn revalidate() {
let query = TestContextImpl::default();
2018-10-19 01:26:48 +00:00
query.memoized2();
query.assert_log(&["Memoized2 invoked", "Memoized1 invoked", "Volatile invoked"]);
2018-10-19 01:26:48 +00:00
query.memoized2();
query.assert_log(&[]);
2018-09-30 11:32:24 +00:00
// Second generation: volatile will change (to 1) but memoized1
// will not (still 0, as 1/2 = 0)
query.salsa_runtime().next_revision();
2018-10-19 01:26:48 +00:00
query.memoized2();
query.assert_log(&["Memoized2 invoked", "Memoized1 invoked", "Volatile invoked"]);
2018-10-19 01:26:48 +00:00
query.memoized2();
2018-09-30 11:32:24 +00:00
query.assert_log(&[]);
// Third generation: volatile will change (to 2) and memoized1
// will too (to 1). Therefore, after validating that Memoized1
// changed, we now invoke Memoized2.
query.salsa_runtime().next_revision();
2018-10-19 01:26:48 +00:00
query.memoized2();
query.assert_log(&["Memoized2 invoked", "Memoized1 invoked", "Volatile invoked"]);
2018-09-30 11:32:24 +00:00
2018-10-19 01:26:48 +00:00
query.memoized2();
2018-09-30 11:32:24 +00:00
query.assert_log(&[]);
}