use std::sync::atomic::{AtomicU32, Ordering};
use crate::{define_input, define_intermediate, impl_storage, storage::HashMapStorage};
#[derive(Default)]
struct EarlyCutoff {
inputs: HashMapStorage<IntInput>,
add1s: HashMapStorage<Five>,
add2s: HashMapStorage<Six>,
add3s: HashMapStorage<Seven>,
}
impl_storage!(EarlyCutoff,
inputs: IntInput,
add1s: Five,
add2s: Six,
add3s: Seven,
);
static INTERMEDIATES_RUN: AtomicU32 = AtomicU32::new(0);
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
struct IntInput(u32);
define_input!(0, IntInput -> u32, EarlyCutoff);
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
struct Five(u32);
define_intermediate!(1, Five -> u32, EarlyCutoff, |ctx, db| {
INTERMEDIATES_RUN.fetch_add(1, Ordering::SeqCst);
let _ = db.get(IntInput(ctx.0));
5
});
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
struct Six(u32);
define_intermediate!(2, Six -> u32, EarlyCutoff, |ctx, db| {
INTERMEDIATES_RUN.fetch_add(1, Ordering::SeqCst);
db.get(Five(ctx.0)) + 1
});
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
struct Seven(u32);
define_intermediate!(3, Seven -> u32, EarlyCutoff, |ctx, db| {
INTERMEDIATES_RUN.fetch_add(1, Ordering::SeqCst);
db.get(Six(ctx.0)) + 1
});
type Db = crate::Db<EarlyCutoff>;
#[test]
fn early_cutoff() {
let mut db = Db::new();
db.update_input(IntInput(5), 5);
assert_eq!(db.get(Seven(5)), 7);
assert_eq!(INTERMEDIATES_RUN.load(Ordering::SeqCst), 3);
assert_eq!(db.get(Seven(5)), 7);
assert_eq!(INTERMEDIATES_RUN.load(Ordering::SeqCst), 3);
db.update_input(IntInput(100), 100);
assert_eq!(db.get(Seven(5)), 7);
assert_eq!(INTERMEDIATES_RUN.load(Ordering::SeqCst), 3);
db.update_input(IntInput(5), 15);
assert_eq!(db.get(Seven(5)), 7);
assert_eq!(INTERMEDIATES_RUN.load(Ordering::SeqCst), 4);
}