in resctl-bench/src/bench/iocost_tune.rs [877:968]
fn parse(&self, spec: &JobSpec, _prev_data: Option<&JobData>) -> Result<Box<dyn Job>> {
let mut job = IoCostTuneJob::default();
let mut prop_groups = spec.props[1..].to_owned();
job.sels = [
DataSel::MOF,
DataSel::AMOF,
DataSel::AMOFDelta,
DataSel::Isol,
DataSel::LatImp,
DataSel::WorkCsv,
DataSel::RLat("50".to_owned(), "mean".to_owned()),
DataSel::RLat("99".to_owned(), "mean".to_owned()),
DataSel::RLat("50".to_owned(), "99".to_owned()),
DataSel::RLat("99".to_owned(), "99".to_owned()),
DataSel::RLat("50".to_owned(), "100".to_owned()),
DataSel::RLat("100".to_owned(), "100".to_owned()),
DataSel::WLat("50".to_owned(), "mean".to_owned()),
DataSel::WLat("99".to_owned(), "mean".to_owned()),
DataSel::WLat("50".to_owned(), "99".to_owned()),
DataSel::WLat("99".to_owned(), "99".to_owned()),
DataSel::WLat("50".to_owned(), "100".to_owned()),
DataSel::WLat("100".to_owned(), "100".to_owned()),
]
.iter()
.cloned()
.collect();
for (k, v) in spec.props[0].iter() {
match k.as_str() {
"gran" => job.gran = v.parse::<f64>()?,
"scale-min" => job.scale_min = parse_frac(v)? * 100.0,
"scale-max" => job.scale_max = parse_frac(v)? * 100.0,
k => {
let sel = DataSel::parse(k)?;
if v.len() > 0 {
bail!(
"Plot data selector {:?} can't have value but has {:?}",
k,
v
);
}
job.sels.insert(sel);
}
}
}
if job.gran <= 0.0 || job.scale_min <= 0.0 || job.scale_min >= job.scale_max {
bail!("`gran`, `scale_min` and/or `scale_max` invalid");
}
if prop_groups.len() == 0 {
let mut push_props = |props: &[(&str, &str)]| {
prop_groups.push(
props
.iter()
.map(|(k, v)| (k.to_string(), v.to_string()))
.collect(),
)
};
push_props(&[("name", "naive")]);
push_props(&[("name", "bandwidth"), ("amof", "max-vrate")]);
push_props(&[("name", "isolated-bandwidth"), ("isolated-bandwidth", "")]);
push_props(&[("name", "isolation"), ("amof-delta", "min")]);
push_props(&[("name", "rlat-99-q1"), ("rlat-99", "q1")]);
push_props(&[("name", "rlat-99-q2"), ("rlat-99", "q2")]);
push_props(&[("name", "rlat-99-q3"), ("rlat-99", "q3")]);
push_props(&[("name", "rlat-99-q4"), ("rlat-99", "q4")]);
}
for props in prop_groups.iter() {
let mut rule = QoSRule::default();
let mut props = props.clone();
if let Some(name) = props.remove("name") {
rule.name = name.to_string();
} else {
bail!("Each rule must have a name");
}
let target = QoSTarget::parse(props)?;
for sel in target.sels().into_iter() {
job.sels.insert(sel);
}
rule.target = target;
job.rules.push(rule);
}
Ok(Box::new(job))
}