pub const NOMINAL_LEN: f64 = 4096.0;
#[must_use]
pub fn survival(f: f64, len: f64) -> f64 {
1.0 - (1.0 - f).powf(len)
}
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct CostFact {
pub fallthrough: f64,
pub len: f64,
pub sieve: f64,
pub rival: f64,
}
impl CostFact {
#[must_use]
pub fn total(self) -> f64 {
self.sieve + survival(self.fallthrough, self.len) * self.rival
}
#[must_use]
pub fn pays(self) -> bool {
self.total() < self.rival
}
#[must_use]
pub fn speedup(self) -> f64 {
self.rival / self.total()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn survival_rises_faster_than_fallthrough() {
assert!(survival(0.01, NOMINAL_LEN) > 0.99);
assert!(survival(1e-6, NOMINAL_LEN) < 0.01);
}
#[test]
fn a_sieve_never_pays_in_front_of_a_free_rival() {
let fact = CostFact {
fallthrough: 0.0,
len: NOMINAL_LEN,
sieve: 0.5,
rival: 0.1,
};
assert!(
!fact.pays(),
"a cheap rival must stand the sieve down on its own"
);
}
}