fn plot_spec_factory()

in resctl-demo/src/graph.rs [493:694]


fn plot_spec_factory(id: PlotId) -> PlotSpec {
    fn rps_spec(idx: usize, range_factor: f64) -> PlotSpec {
        PlotSpec {
            sel: Box::new(move |rep: &Report| rep.hashd[idx].rps),
            aggr: PlotDataAggr::AVG,
            title: Box::new(|| "rps".into()),
            min: Box::new(|| 0.0),
            max: Box::new(move || AGENT_FILES.bench().hashd.rps_max as f64 * range_factor),
        }
    }
    fn lat_spec(idx: usize) -> PlotSpec {
        PlotSpec {
            sel: Box::new(move |rep: &Report| rep.hashd[idx].lat.ctl * 1000.0),
            aggr: PlotDataAggr::MAX,
            title: Box::new(|| "lat".into()),
            min: Box::new(|| 0.0),
            max: Box::new(|| 0.0),
        }
    }
    fn cpu_spec(slice: &'static str) -> PlotSpec {
        PlotSpec {
            sel: Box::new(move |rep: &Report| rep.usages.get(slice).unwrap().cpu_util * 100.0),
            aggr: PlotDataAggr::AVG,
            title: Box::new(move || format!("{}-cpu", slice.trim_end_matches(".slice"))),
            min: Box::new(|| 0.0),
            max: Box::new(|| 100.0),
        }
    }
    fn mem_spec(slice: &'static str) -> PlotSpec {
        PlotSpec {
            sel: Box::new(move |rep: &Report| {
                rep.usages.get(slice).unwrap().mem_bytes as f64 / (1 << 30) as f64
            }),
            aggr: PlotDataAggr::AVG,
            title: Box::new(move || format!("{}-mem", slice.trim_end_matches(".slice"))),
            min: Box::new(|| 0.0),
            max: Box::new(|| 0.0),
        }
    }
    fn swap_spec(slice: &'static str) -> PlotSpec {
        PlotSpec {
            sel: Box::new(move |rep: &Report| {
                rep.usages.get(slice).unwrap().swap_bytes as f64 / (1 << 30) as f64
            }),
            aggr: PlotDataAggr::AVG,
            title: Box::new(move || format!("{}-swap", slice.trim_end_matches(".slice"))),
            min: Box::new(|| 0.0),
            max: Box::new(|| 0.0),
        }
    }
    fn io_spec(slice: &'static str) -> PlotSpec {
        PlotSpec {
            sel: Box::new(move |rep: &Report| {
                (rep.usages.get(slice).unwrap().io_util * 100.0).min(200.0)
            }),
            aggr: PlotDataAggr::AVG,
            title: Box::new(move || format!("{}-util", slice.trim_end_matches(".slice"))),
            min: Box::new(|| 0.0),
            max: Box::new(|| 0.0),
        }
    }
    fn io_read_spec(slice: &'static str) -> PlotSpec {
        PlotSpec {
            sel: Box::new(move |rep: &Report| {
                rep.usages.get(slice).unwrap().io_rbps as f64 / (1024.0 * 1024.0)
            }),
            aggr: PlotDataAggr::AVG,
            title: Box::new(move || format!("{}-read-Mbps", slice.trim_end_matches(".slice"))),
            min: Box::new(|| 0.0),
            max: Box::new(|| 0.0),
        }
    }
    fn io_write_spec(slice: &'static str) -> PlotSpec {
        PlotSpec {
            sel: Box::new(move |rep: &Report| {
                rep.usages.get(slice).unwrap().io_wbps as f64 / (1024.0 * 1024.0)
            }),
            aggr: PlotDataAggr::AVG,
            title: Box::new(move || format!("{}-write-Mbps", slice.trim_end_matches(".slice"))),
            min: Box::new(|| 0.0),
            max: Box::new(|| 0.0),
        }
    }
    fn cpu_psi_some_spec(slice: &'static str) -> PlotSpec {
        PlotSpec {
            sel: Box::new(move |rep: &Report| {
                rep.usages.get(slice).unwrap().cpu_pressures.0 * 100.0
            }),
            aggr: PlotDataAggr::AVG,
            title: Box::new(move || format!("{}-cpu-psi-some", slice.trim_end_matches(".slice"))),
            min: Box::new(|| 0.0),
            max: Box::new(|| 100.0),
        }
    }
    fn mem_psi_spec(slice: &'static str, is_full: bool) -> PlotSpec {
        let which = if is_full { "full" } else { "some" };
        PlotSpec {
            sel: Box::new(move |rep: &Report| {
                if is_full {
                    rep.usages.get(slice).unwrap().mem_pressures.1 * 100.0
                } else {
                    rep.usages.get(slice).unwrap().mem_pressures.0 * 100.0
                }
            }),
            aggr: PlotDataAggr::AVG,
            title: Box::new(move || {
                format!("{}-mem-psi-{}", slice.trim_end_matches(".slice"), which)
            }),
            min: Box::new(|| 0.0),
            max: Box::new(|| 100.0),
        }
    }
    fn io_psi_spec(slice: &'static str, is_full: bool) -> PlotSpec {
        let which = if is_full { "full" } else { "some" };
        PlotSpec {
            sel: Box::new(move |rep: &Report| {
                if is_full {
                    rep.usages.get(slice).unwrap().io_pressures.1 * 100.0
                } else {
                    rep.usages.get(slice).unwrap().io_pressures.0 * 100.0
                }
            }),
            aggr: PlotDataAggr::AVG,
            title: Box::new(move || {
                format!("{}-io-psi-{}", slice.trim_end_matches(".slice"), which)
            }),
            min: Box::new(|| 0.0),
            max: Box::new(|| 100.0),
        }
    }
    fn io_lat_spec(iotype: &'static str, pct: &'static str) -> PlotSpec {
        PlotSpec {
            sel: Box::new(move |rep: &Report| rep.iolat.map[iotype][pct] * 1000.0),
            aggr: PlotDataAggr::MAX,
            title: Box::new(move || format!("{}-lat-p{}", iotype, pct)),
            min: Box::new(|| 0.0),
            max: Box::new(|| 0.0),
        }
    }

    match id {
        PlotId::HashdARps => rps_spec(0, 1.1),
        PlotId::HashdALat => lat_spec(0),
        PlotId::HashdBRps => rps_spec(1, 1.1),
        PlotId::HashdBLat => lat_spec(1),
        PlotId::HashdARpsMax100 => rps_spec(0, 1.0),
        PlotId::WorkCpu => cpu_spec("workload.slice"),
        PlotId::SideCpu => cpu_spec("sideload.slice"),
        PlotId::SysCpu => cpu_spec("system.slice"),
        PlotId::WorkMem => mem_spec("workload.slice"),
        PlotId::SideMem => mem_spec("sideload.slice"),
        PlotId::SysMem => mem_spec("system.slice"),
        PlotId::WorkIo => io_spec("workload.slice"),
        PlotId::SideIo => io_spec("sideload.slice"),
        PlotId::SysIo => io_spec("system.slice"),
        PlotId::RootIo => io_spec("-.slice"),
        PlotId::WorkSwap => swap_spec("workload.slice"),
        PlotId::SideSwap => swap_spec("sideload.slice"),
        PlotId::SysSwap => swap_spec("system.slice"),
        PlotId::WorkRead => io_read_spec("workload.slice"),
        PlotId::SideRead => io_read_spec("sideload.slice"),
        PlotId::SysRead => io_read_spec("system.slice"),
        PlotId::WorkWrite => io_write_spec("workload.slice"),
        PlotId::SideWrite => io_write_spec("sideload.slice"),
        PlotId::SysWrite => io_write_spec("system.slice"),
        PlotId::WorkCpuPsiSome => cpu_psi_some_spec("workload.slice"),
        PlotId::SideCpuPsiSome => cpu_psi_some_spec("sideload.slice"),
        PlotId::SysCpuPsiSome => cpu_psi_some_spec("system.slice"),
        PlotId::WorkMemPsiSome => mem_psi_spec("workload.slice", false),
        PlotId::SideMemPsiSome => mem_psi_spec("sideload.slice", false),
        PlotId::SysMemPsiSome => mem_psi_spec("system.slice", false),
        PlotId::WorkIoPsiSome => io_psi_spec("workload.slice", false),
        PlotId::SideIoPsiSome => io_psi_spec("sideload.slice", false),
        PlotId::SysIoPsiSome => io_psi_spec("system.slice", false),
        PlotId::WorkMemPsiFull => mem_psi_spec("workload.slice", true),
        PlotId::SideMemPsiFull => mem_psi_spec("sideload.slice", true),
        PlotId::SysMemPsiFull => mem_psi_spec("system.slice", true),
        PlotId::WorkIoPsiFull => io_psi_spec("workload.slice", true),
        PlotId::SideIoPsiFull => io_psi_spec("sideload.slice", true),
        PlotId::SysIoPsiFull => io_psi_spec("system.slice", true),
        PlotId::ReadLatP50 => io_lat_spec("read", "50"),
        PlotId::ReadLatP90 => io_lat_spec("read", "90"),
        PlotId::ReadLatP99 => io_lat_spec("read", "99"),
        PlotId::WriteLatP50 => io_lat_spec("write", "50"),
        PlotId::WriteLatP90 => io_lat_spec("write", "90"),
        PlotId::WriteLatP99 => io_lat_spec("write", "99"),
        PlotId::IoCostVrate => PlotSpec {
            sel: Box::new(move |rep: &Report| rep.iocost.vrate),
            aggr: PlotDataAggr::AVG,
            title: Box::new(move || "vrate%".into()),
            min: Box::new(|| 0.0),
            max: Box::new(|| 0.0),
        },
        PlotId::Dummy => PlotSpec {
            sel: Box::new(move |_rep: &Report| 0.0),
            aggr: PlotDataAggr::AVG,
            title: Box::new(move || "".into()),
            min: Box::new(|| 0.0),
            max: Box::new(|| 0.0),
        },
    }
}