in resctl-bench/src/bench/iocost_tune.rs [470:545]
fn parse(mut props: BTreeMap<String, String>) -> Result<QoSTarget> {
if props.len() == 0 {
return Ok(Default::default());
}
if let Some(v) = props.remove("vrate") {
let range = Self::parse_vrate_range(&v)?;
let mut ref_pcts = (None, None);
if let Self::VrateRange(_, dfl_ref_pcts) = QoSTarget::default() {
ref_pcts = dfl_ref_pcts;
}
for (k, v) in props.iter() {
match k.as_str() {
"rpct" => {
ref_pcts.0 = if Self::is_float_zero(v) {
None
} else {
Some(v.to_string())
}
}
"wpct" => {
ref_pcts.1 = if Self::is_float_zero(v) {
None
} else {
Some(v.to_string())
}
}
k => bail!("Invalid vrate target option {:?}", k),
}
}
return Ok(Self::VrateRange(range, ref_pcts));
}
if props.len() != 1 {
bail!("Each QoS rule should contain one QoS target");
}
let (k, v) = props.into_iter().next().unwrap();
let k = k.to_lowercase();
let v = v.to_lowercase();
match k.as_str() {
"isolated-bandwidth" => Ok(Self::IsolatedBandwidth),
k => {
let sel = DataSel::parse(k)?;
match &sel {
DataSel::MOF => match v.as_str() {
"max" => Ok(Self::MOFMax),
v => bail!("Invalid {:?} value {:?}", &sel, &v),
},
DataSel::AMOF => match v.as_str() {
"max" => Ok(Self::AMOFMax),
"max-vrate" => Ok(Self::AMOFMaxVrate),
v => bail!("Invalid {:?} value {:?}", &sel, &v),
},
DataSel::AMOFDelta => match v.as_str() {
"min" => Ok(Self::AMOFDeltaMin),
v => bail!("Invalid {:?} value {:?}", &sel, &v),
},
DataSel::RLat(_, time_pct) | DataSel::WLat(_, time_pct) => {
if time_pct != "mean" {
bail!("Latency range target should have \"mean\" for time percentile");
}
let (low, high) = match v.as_str() {
"q1" => (0.75, 1.00),
"q2" => (0.50, 0.75),
"q3" => (0.25, 0.50),
"q4" => (0.0, 0.25),
v => Self::parse_frac_range(v)?,
};
Ok(Self::LatRange(sel.clone(), (low, high)))
}
_ => bail!("Unsupported QoSTarget selector {:?}", &sel),
}
}
}
}