test for "shallow constant sweep"

This commit is contained in:
Niko Matsakis 2018-10-24 04:38:38 -04:00
parent 7f1d1995aa
commit b9ae3dbc4c
4 changed files with 180 additions and 0 deletions

26
tests/gc/db.rs Normal file
View file

@ -0,0 +1,26 @@
use crate::group;
#[derive(Default)]
pub struct DatabaseImpl {
runtime: salsa::Runtime<DatabaseImpl>,
}
impl salsa::Database for DatabaseImpl {
fn salsa_runtime(&self) -> &salsa::Runtime<DatabaseImpl> {
&self.runtime
}
}
salsa::database_storage! {
pub struct DatabaseImplStorage for DatabaseImpl {
impl group::GcDatabase {
fn min() for group::Min;
fn max() for group::Max;
fn use_triangular() for group::UseTriangular;
fn fibonacci() for group::Fibonacci;
fn triangular() for group::Triangular;
fn compute() for group::Compute;
fn compute_all() for group::ComputeAll;
}
}
}

64
tests/gc/group.rs Normal file
View file

@ -0,0 +1,64 @@
salsa::query_group! {
pub(crate) trait GcDatabase: salsa::Database {
fn min() -> usize {
type Min;
storage input;
}
fn max() -> usize {
type Max;
storage input;
}
fn use_triangular(key: usize) -> bool {
type UseTriangular;
storage input;
}
fn fibonacci(key: usize) -> usize {
type Fibonacci;
}
fn triangular(key: usize) -> usize {
type Triangular;
}
fn compute(key: usize) -> usize {
type Compute;
}
fn compute_all() -> Vec<usize> {
type ComputeAll;
}
}
}
fn fibonacci(db: &impl GcDatabase, key: usize) -> usize {
if key == 0 {
0
} else if key == 1 {
1
} else {
db.fibonacci(key - 1) + db.fibonacci(key - 2)
}
}
fn triangular(db: &impl GcDatabase, key: usize) -> usize {
if key == 0 {
0
} else {
db.triangular(key - 1) + key
}
}
fn compute(db: &impl GcDatabase, key: usize) -> usize {
if db.use_triangular(key) {
db.triangular(key)
} else {
db.fibonacci(key)
}
}
fn compute_all(db: &impl GcDatabase) -> Vec<usize> {
(db.min()..db.max()).map(|v| db.compute(v)).collect()
}

4
tests/gc/main.rs Normal file
View file

@ -0,0 +1,4 @@
mod db;
mod derived_tests;
mod group;
mod shallow_constant_tests;

View file

@ -0,0 +1,86 @@
use crate::db;
use crate::group::{Fibonacci, GcDatabase};
use salsa::debug::DebugQueryTable;
use salsa::Database;
// For constant values (like `fibonacci`), we only keep the values
// that were used in the latest revision, not the sub-values that
// they required to be computed.
#[test]
fn one_rev() {
let db = db::DatabaseImpl::default();
db.fibonacci(5);
let k: Vec<_> = db.query(Fibonacci).keys();
assert_eq!(k.len(), 6);
// Everything was used in this revision, so
// nothing gets collected.
db.sweep_all();
assert_eq!(k.len(), 6);
}
#[test]
fn two_rev_nothing() {
let db = db::DatabaseImpl::default();
db.fibonacci(5);
let k: Vec<_> = db.query(Fibonacci).keys();
assert_eq!(k.len(), 6);
db.salsa_runtime().next_revision();
// Nothing was used in this revision, so
// everything gets collected.
db.sweep_all();
let k: Vec<_> = db.query(Fibonacci).keys();
assert_eq!(k.len(), 0);
}
#[test]
fn two_rev_one_use() {
let db = db::DatabaseImpl::default();
db.fibonacci(5);
let k: Vec<_> = db.query(Fibonacci).keys();
assert_eq!(k.len(), 6);
db.salsa_runtime().next_revision();
db.fibonacci(5);
// fibonacci is a constant, so it will not be invalidated,
// hence we keep `fibonacci(5)` but remove 0..=4.
db.sweep_all();
let k: Vec<_> = db.query(Fibonacci).keys();
assert_eq!(k, vec![5]);
}
#[test]
fn two_rev_two_uses() {
let db = db::DatabaseImpl::default();
db.fibonacci(5);
let k: Vec<_> = db.query(Fibonacci).keys();
assert_eq!(k.len(), 6);
db.salsa_runtime().next_revision();
db.fibonacci(5);
db.fibonacci(3);
// fibonacci is a constant, so it will not be invalidated,
// hence we keep 3 and 5 but remove the rest.
db.sweep_all();
let mut k: Vec<_> = db.query(Fibonacci).keys();
k.sort();
assert_eq!(k, vec![3, 5]);
}