mirror of
https://github.com/salsa-rs/salsa.git
synced 2025-01-23 05:07:27 +00:00
port another test about lru
This commit is contained in:
parent
04b70f54e3
commit
6645774d55
2 changed files with 52 additions and 2 deletions
|
@ -21,4 +21,12 @@ pub trait HasLogger {
|
||||||
let logs = std::mem::replace(&mut *self.logger().logs.lock().unwrap(), vec![]);
|
let logs = std::mem::replace(&mut *self.logger().logs.lock().unwrap(), vec![]);
|
||||||
expected.assert_eq(&format!("{:#?}", logs));
|
expected.assert_eq(&format!("{:#?}", logs));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Asserts the length of the logs,
|
||||||
|
/// clearing the logged events. This takes `&mut self` because
|
||||||
|
/// it is meant to be run from outside any tracked functions.
|
||||||
|
fn assert_logs_len(&mut self, expected: usize) {
|
||||||
|
let logs = std::mem::replace(&mut *self.logger().logs.lock().unwrap(), vec![]);
|
||||||
|
assert_eq!(logs.len(), expected);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,12 +6,13 @@ use std::sync::{
|
||||||
Arc,
|
Arc,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use salsa_2022_tests::{HasLogger, Logger};
|
||||||
use test_log::test;
|
use test_log::test;
|
||||||
|
|
||||||
#[salsa::jar(db = Db)]
|
#[salsa::jar(db = Db)]
|
||||||
struct Jar(MyInput, get_hot_potato, get_volatile);
|
struct Jar(MyInput, get_hot_potato, get_hot_potato2, get_volatile);
|
||||||
|
|
||||||
trait Db: salsa::DbWithJar<Jar> {}
|
trait Db: salsa::DbWithJar<Jar> + HasLogger {}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq)]
|
#[derive(Debug, PartialEq, Eq)]
|
||||||
struct HotPotato(u32);
|
struct HotPotato(u32);
|
||||||
|
@ -40,9 +41,16 @@ struct MyInput {
|
||||||
|
|
||||||
#[salsa::tracked(jar = Jar, lru = 32)]
|
#[salsa::tracked(jar = Jar, lru = 32)]
|
||||||
fn get_hot_potato(db: &dyn Db, input: MyInput) -> Arc<HotPotato> {
|
fn get_hot_potato(db: &dyn Db, input: MyInput) -> Arc<HotPotato> {
|
||||||
|
db.push_log(format!("get_hot_potato({:?})", input.field(db)));
|
||||||
Arc::new(HotPotato::new(input.field(db)))
|
Arc::new(HotPotato::new(input.field(db)))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[salsa::tracked(jar = Jar)]
|
||||||
|
fn get_hot_potato2(db: &dyn Db, input: MyInput) -> u32 {
|
||||||
|
db.push_log(format!("get_hot_potato2({:?})", input.field(db)));
|
||||||
|
get_hot_potato(db, input).0
|
||||||
|
}
|
||||||
|
|
||||||
#[salsa::tracked(jar = Jar, lru = 32)]
|
#[salsa::tracked(jar = Jar, lru = 32)]
|
||||||
fn get_volatile(db: &dyn Db, _input: MyInput) -> usize {
|
fn get_volatile(db: &dyn Db, _input: MyInput) -> usize {
|
||||||
static COUNTER: AtomicUsize = AtomicUsize::new(0);
|
static COUNTER: AtomicUsize = AtomicUsize::new(0);
|
||||||
|
@ -54,6 +62,7 @@ fn get_volatile(db: &dyn Db, _input: MyInput) -> usize {
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
struct Database {
|
struct Database {
|
||||||
storage: salsa::Storage<Self>,
|
storage: salsa::Storage<Self>,
|
||||||
|
logger: Logger,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl salsa::Database for Database {
|
impl salsa::Database for Database {
|
||||||
|
@ -64,6 +73,12 @@ impl salsa::Database for Database {
|
||||||
|
|
||||||
impl Db for Database {}
|
impl Db for Database {}
|
||||||
|
|
||||||
|
impl HasLogger for Database {
|
||||||
|
fn logger(&self) -> &Logger {
|
||||||
|
&self.logger
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn load_n_potatoes() -> usize {
|
fn load_n_potatoes() -> usize {
|
||||||
N_POTATOES.with(|n| n.load(Ordering::SeqCst))
|
N_POTATOES.with(|n| n.load(Ordering::SeqCst))
|
||||||
}
|
}
|
||||||
|
@ -147,3 +162,30 @@ fn lru_can_be_changed_at_runtime() {
|
||||||
drop(db);
|
drop(db);
|
||||||
assert_eq!(load_n_potatoes(), 0);
|
assert_eq!(load_n_potatoes(), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn lru_keeps_dependency_info() {
|
||||||
|
let mut db = Database::default();
|
||||||
|
let capacity = 32;
|
||||||
|
|
||||||
|
// Invoke `get_hot_potato2` 33 times. This will (in turn) invoke
|
||||||
|
// `get_hot_potato`, which will trigger LRU after 32 executions.
|
||||||
|
let inputs: Vec<MyInput> = (0..(capacity + 1))
|
||||||
|
.map(|i| MyInput::new(&mut db, i as u32))
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
for (i, input) in inputs.iter().enumerate() {
|
||||||
|
let x = get_hot_potato2(&db, *input);
|
||||||
|
assert_eq!(x as usize, i);
|
||||||
|
}
|
||||||
|
|
||||||
|
// We want to test that calls to `get_hot_potato2` are still considered
|
||||||
|
// clean. Check that no new executions occur as we go here.
|
||||||
|
db.assert_logs_len((capacity + 1) * 2);
|
||||||
|
|
||||||
|
// calling `get_hot_potato2(0)` has to check that `get_hot_potato(0)` is still valid;
|
||||||
|
// even though we've evicted it (LRU), we find that it is still good
|
||||||
|
let p = get_hot_potato2(&db, *inputs.first().unwrap());
|
||||||
|
assert_eq!(p, 0);
|
||||||
|
db.assert_logs_len(0);
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue