in resctl-demo/src/graph.rs [238:312]
fn new(cb_sink: cursive::CbSink, tag: GraphTag, mut specs_input: Vec<PlotSpec>) -> Self {
assert!(specs_input.len() > 0 && specs_input.len() < 4);
let dummy_sel = |_: &Report| 0.0;
let mut fns: Vec<Box<dyn Fn(&Report) -> f64>> = vec![
Box::new(dummy_sel),
Box::new(dummy_sel),
Box::new(dummy_sel),
];
let mut aggrs = vec![PlotDataAggr::AVG, PlotDataAggr::AVG, PlotDataAggr::AVG];
let mut specs = Vec::new();
let mut idx = specs_input.len();
while let Some(spec) = specs_input.pop() {
let (sel, aggr, title, min, max) =
(spec.sel, spec.aggr, spec.title, spec.min, spec.max);
idx -= 1;
fns[idx] = sel;
aggrs[idx] = aggr;
specs.insert(
0,
PlotSpec {
sel: Box::new(dummy_sel),
aggr,
title,
min,
max,
},
);
}
let sel_fn = move |rep: &Report| GraphData(fns[0](rep), fns[1](rep), fns[2](rep));
let aggrs_clone = aggrs.clone();
let acc_fn = move |dacc: &mut GraphData, data: &GraphData| {
match aggrs[0] {
PlotDataAggr::AVG => dacc.0 += data.0,
PlotDataAggr::MAX => dacc.0 = dacc.0.max(data.0),
}
match aggrs[1] {
PlotDataAggr::AVG => dacc.1 += data.1,
PlotDataAggr::MAX => dacc.1 = dacc.1.max(data.1),
}
match aggrs[2] {
PlotDataAggr::AVG => dacc.2 += data.2,
PlotDataAggr::MAX => dacc.2 = dacc.2.max(data.2),
}
};
let aggrs = aggrs_clone;
let aggr_fn = move |dacc: &mut GraphData, nr_samples: usize| {
if aggrs[0] == PlotDataAggr::AVG {
dacc.0 /= nr_samples as f64;
}
if aggrs[1] == PlotDataAggr::AVG {
dacc.1 /= nr_samples as f64;
}
if aggrs[2] == PlotDataAggr::AVG {
dacc.2 /= nr_samples as f64;
}
};
Self {
cb_sink,
tag,
specs,
data: ReportDataSet::<GraphData>::new(
Box::new(sel_fn),
Box::new(acc_fn),
Box::new(aggr_fn),
),
}
}