response_time_analysis/arrival/
aggregated.rs

1use itertools::Itertools;
2
3use super::ArrivalBound;
4use crate::time::Duration;
5
6// repeated implementation for Vec<T> because otherwise Vec<Box<dyn ArrivalBound>>
7// is not recognized as an ArrivalBound, despite the above blanket implementation for
8impl<T: ArrivalBound> ArrivalBound for Vec<T> {
9    fn number_arrivals(&self, delta: Duration) -> usize {
10        self.iter().map(|ab| ab.number_arrivals(delta)).sum()
11    }
12
13    fn steps_iter<'a>(&'a self) -> Box<dyn Iterator<Item = Duration> + 'a> {
14        Box::new(self.iter().map(|ab| ab.steps_iter()).kmerge().dedup())
15    }
16
17    fn clone_with_jitter(&self, jitter: Duration) -> Box<dyn ArrivalBound> {
18        let cloned: Vec<Box<dyn ArrivalBound>> =
19            self.iter().map(|ab| ab.clone_with_jitter(jitter)).collect();
20        Box::new(cloned)
21    }
22}
23
24#[derive(Clone, Debug)]
25struct SumOf<AB1: ArrivalBound, AB2: ArrivalBound>(AB1, AB2);
26
27/// The sum of two arrival bounds, representing the joint arrival bound.
28pub fn sum_of<AB1: ArrivalBound, AB2: ArrivalBound>(ab1: AB1, ab2: AB2) -> impl ArrivalBound {
29    SumOf(ab1, ab2)
30}
31
32impl<AB1: ArrivalBound, AB2: ArrivalBound> ArrivalBound for SumOf<AB1, AB2> {
33    fn number_arrivals(&self, delta: Duration) -> usize {
34        self.0.number_arrivals(delta) + self.1.number_arrivals(delta)
35    }
36
37    fn steps_iter<'a>(&'a self) -> Box<dyn Iterator<Item = Duration> + 'a> {
38        Box::new(self.0.steps_iter().merge(self.1.steps_iter()).dedup())
39    }
40
41    fn clone_with_jitter(&self, jitter: Duration) -> Box<dyn ArrivalBound> {
42        Box::new(SumOf(
43            self.0.clone_with_jitter(jitter),
44            self.1.clone_with_jitter(jitter),
45        ))
46    }
47}