response_time_analysis/demand/
aggregate.rs

1use itertools::Itertools;
2
3use super::{AggregateRequestBound, RequestBound};
4use crate::time::{Duration, Service};
5
6/// A wrapper type for representing the total demand of a vector of
7/// individual demand sources (e.g., all higher-priority tasks).
8#[derive(Clone, Debug)]
9pub struct Aggregate<T> {
10    individual: Vec<T>,
11}
12
13impl<T> Aggregate<T> {
14    pub fn new(components: Vec<T>) -> Self {
15        Aggregate {
16            individual: components,
17        }
18    }
19}
20
21impl<T: RequestBound> RequestBound for Aggregate<T> {
22    fn service_needed(&self, delta: Duration) -> Service {
23        self.individual
24            .iter()
25            .map(|rbf| rbf.service_needed(delta))
26            .sum()
27    }
28
29    fn least_wcet_in_interval(&self, delta: Duration) -> Service {
30        self.individual
31            .iter()
32            .map(|rbf| rbf.least_wcet_in_interval(delta))
33            .min()
34            .unwrap_or_else(Service::none)
35    }
36
37    fn steps_iter<'a>(&'a self) -> Box<dyn Iterator<Item = Duration> + 'a> {
38        Box::new(
39            self.individual
40                .iter()
41                .map(|rbf| rbf.steps_iter())
42                .kmerge()
43                .dedup(),
44        )
45    }
46
47    fn job_cost_iter<'a>(&'a self, delta: Duration) -> Box<dyn Iterator<Item = Service> + 'a> {
48        Box::new(
49            self.individual
50                .iter()
51                .map(|rbf| rbf.job_cost_iter(delta))
52                .kmerge(),
53        )
54    }
55}
56
57impl<T: RequestBound> AggregateRequestBound for Aggregate<T> {
58    fn service_needed_by_n_jobs_per_component(&self, delta: Duration, max_jobs: usize) -> Service {
59        self.individual
60            .iter()
61            .map(|rbf| rbf.service_needed_by_n_jobs(delta, max_jobs))
62            .sum()
63    }
64}