port more tests about lru

This commit is contained in:
XFFXFF 2022-08-17 17:22:12 +08:00
parent d080e349ef
commit 341fc80726
2 changed files with 34 additions and 5 deletions

View file

@ -46,6 +46,9 @@ pub(crate) struct Options<A: AllowedOptions> {
/// If this is `Some`, the value is the `<ident>`.
pub data: Option<syn::Ident>,
/// The `lru = <usize>` option is used to set the lru capacity for a tracked function.
///
/// If this is `Some`, the value is the `<usize>`.
pub lru: Option<syn::LitInt>,
/// Remember the `A` parameter, which plays no role after parsing.

View file

@ -1,15 +1,14 @@
//! Test that a `tracked` fn on a `salsa::input`
//! Test that a `tracked` fn with lru options
//! compiles and executes successfully.
use std::sync::{atomic::{AtomicUsize, Ordering}, Arc};
use salsa_2022_tests::{HasLogger, Logger};
use expect_test::expect;
use test_log::test;
#[salsa::jar(db = Db)]
struct Jar(MyInput, get_hot_potato, EmptyInput);
struct Jar(MyInput, get_hot_potato, EmptyInput, get_volatile);
trait Db: salsa::DbWithJar<Jar> + HasLogger {}
@ -43,6 +42,13 @@ fn get_hot_potato(db: &dyn Db, input: MyInput) -> Arc<HotPotato> {
Arc::new(HotPotato::new(input.field(db)))
}
#[salsa::tracked(jar = Jar, lru = 32)]
fn get_volatile(db: &dyn Db, _input: MyInput) -> usize {
static COUNTER: AtomicUsize = AtomicUsize::new(0);
db.salsa_runtime().report_untracked_read();
COUNTER.fetch_add(1, Ordering::SeqCst)
}
#[salsa::input(jar = Jar)]
struct EmptyInput {}
@ -72,7 +78,7 @@ fn load_n_potatoes() -> usize {
}
#[test]
fn execute() {
fn lru_works() {
let mut db = Database::default();
assert_eq!(load_n_potatoes(), 0);
@ -81,6 +87,26 @@ fn execute() {
let p = get_hot_potato(&db, input);
assert_eq!(p.0, i)
}
EmptyInput::new(&mut db);
// Create a new input to change the revision, and trigger the GC
MyInput::new(&mut db, 0);
assert_eq!(load_n_potatoes(), 32);
}
#[test]
fn lru_doesnt_break_volatile_queries() {
let mut db = Database::default();
// Create all inputs first, so that there are no revision changes among calls to `get_volatile`
let inputs: Vec<MyInput> = (0..128usize).map(|i| MyInput::new(&mut db, i as u32)).collect();
// Here, we check that we execute each volatile query at most once, despite
// LRU. That does mean that we have more values in DB than the LRU capacity,
// but it's much better than inconsistent results from volatile queries!
for _ in 0..3 {
for (i, input) in inputs.iter().enumerate() {
let x = get_volatile(&db, *input);
assert_eq!(x, i);
}
}
}