response_time_analysis/demand/
slice.rs

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