use auto_impl::auto_impl;
use itertools::Itertools;
use crate::time::Duration;
#[auto_impl(&, Box, Rc)]
pub trait ArrivalBound {
fn number_arrivals(&self, delta: Duration) -> usize;
fn steps_iter<'a>(&'a self) -> Box<dyn Iterator<Item = Duration> + 'a> {
self.brute_force_steps_iter()
}
fn brute_force_steps_iter<'a>(&'a self) -> Box<dyn Iterator<Item = Duration> + 'a> {
let (a1, a2) = (0..)
.map(move |delta| (delta, self.number_arrivals(Duration::from(delta))))
.tee();
Box::new(
a1.zip(a2.skip(1))
.filter(|((_, njobs1), (_, njobs2))| njobs1 != njobs2)
.map(|((_, _), (d2, _))| Duration::from(d2)),
)
}
fn clone_with_jitter(&self, jitter: Duration) -> Box<dyn ArrivalBound>;
}
mod aggregated;
mod arrival_curve_prefix;
mod curve;
mod dmin;
mod never;
mod periodic;
mod poisson;
mod propagated;
mod slice;
mod sporadic;
pub use aggregated::sum_of;
pub use arrival_curve_prefix::ArrivalCurvePrefix;
pub use curve::{Curve, ExtrapolatingCurve};
pub use dmin::{delta_min_iter, nonzero_delta_min_iter};
pub use never::Never;
pub use periodic::Periodic;
pub use poisson::{ApproximatedPoisson, Poisson};
pub use propagated::Propagated;
pub use sporadic::Sporadic;
fn divide_with_ceil(a: Duration, b: Duration) -> u64 {
a / b + (a % b > Duration::from(0)) as u64
}
#[cfg(test)]
mod tests;