Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/salsa/tests/incremental/memoized_volatile.rs')
-rw-r--r--crates/salsa/tests/incremental/memoized_volatile.rs77
1 files changed, 77 insertions, 0 deletions
diff --git a/crates/salsa/tests/incremental/memoized_volatile.rs b/crates/salsa/tests/incremental/memoized_volatile.rs
new file mode 100644
index 0000000000..6dc5030063
--- /dev/null
+++ b/crates/salsa/tests/incremental/memoized_volatile.rs
@@ -0,0 +1,77 @@
+use crate::implementation::{TestContext, TestContextImpl};
+use salsa::{Database, Durability};
+
+#[salsa::query_group(MemoizedVolatile)]
+pub(crate) trait MemoizedVolatileContext: TestContext {
+ // Queries for testing a "volatile" value wrapped by
+ // memoization.
+ fn memoized2(&self) -> usize;
+ fn memoized1(&self) -> usize;
+ fn volatile(&self) -> usize;
+}
+
+fn memoized2(db: &dyn MemoizedVolatileContext) -> usize {
+ db.log().add("Memoized2 invoked");
+ db.memoized1()
+}
+
+fn memoized1(db: &dyn MemoizedVolatileContext) -> usize {
+ db.log().add("Memoized1 invoked");
+ let v = db.volatile();
+ v / 2
+}
+
+fn volatile(db: &dyn MemoizedVolatileContext) -> usize {
+ db.log().add("Volatile invoked");
+ db.salsa_runtime().report_untracked_read();
+ 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.
+ query.volatile();
+ query.volatile();
+ query.assert_log(&["Volatile invoked"]);
+}
+
+/// 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]
+fn revalidate() {
+ let mut query = TestContextImpl::default();
+
+ query.memoized2();
+ query.assert_log(&["Memoized2 invoked", "Memoized1 invoked", "Volatile invoked"]);
+
+ 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_mut().synthetic_write(Durability::LOW);
+ query.memoized2();
+ query.assert_log(&["Volatile invoked", "Memoized1 invoked"]);
+ query.memoized2();
+ 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_mut().synthetic_write(Durability::LOW);
+
+ query.memoized2();
+ query.assert_log(&["Volatile invoked", "Memoized1 invoked", "Memoized2 invoked"]);
+
+ query.memoized2();
+ query.assert_log(&[]);
+}