fn parse()

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))
    }