pub mod envelope;
pub mod motifs;
pub mod replay;
use crate::residual::{ResidualClass, ResidualStream};
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub enum MotifClass {
PlanRegressionOnset,
CardinalityMismatchRegime,
ContentionRamp,
CacheCollapse,
WorkloadPhaseTransition,
}
impl MotifClass {
pub const ALL: [MotifClass; 5] = [
Self::PlanRegressionOnset,
Self::CardinalityMismatchRegime,
Self::ContentionRamp,
Self::CacheCollapse,
Self::WorkloadPhaseTransition,
];
pub fn name(&self) -> &'static str {
match self {
Self::PlanRegressionOnset => "plan_regression_onset",
Self::CardinalityMismatchRegime => "cardinality_mismatch_regime",
Self::ContentionRamp => "contention_ramp",
Self::CacheCollapse => "cache_collapse",
Self::WorkloadPhaseTransition => "workload_phase_transition",
}
}
pub fn residual_class(&self) -> ResidualClass {
match self {
Self::PlanRegressionOnset => ResidualClass::PlanRegression,
Self::CardinalityMismatchRegime => ResidualClass::Cardinality,
Self::ContentionRamp => ResidualClass::Contention,
Self::CacheCollapse => ResidualClass::CacheIo,
Self::WorkloadPhaseTransition => ResidualClass::WorkloadPhase,
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Episode {
pub motif: MotifClass,
pub channel: Option<String>,
pub t_start: f64,
pub t_end: f64,
pub peak: f64,
pub ema_at_boundary: f64,
pub trust_sum: f64,
}
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct MotifParams {
pub rho: f64,
pub sigma0: f64,
pub drift_threshold: f64,
pub slew_threshold: f64,
pub min_dwell_seconds: f64,
}
impl MotifParams {
pub fn default_for(class: MotifClass) -> Self {
match class {
MotifClass::PlanRegressionOnset => Self {
rho: 0.9,
sigma0: 0.05,
drift_threshold: 0.20,
slew_threshold: 0.50,
min_dwell_seconds: 5.0,
},
MotifClass::CardinalityMismatchRegime => Self {
rho: 0.9,
sigma0: 0.05,
drift_threshold: 0.5, slew_threshold: 1.0, min_dwell_seconds: 2.0,
},
MotifClass::ContentionRamp => Self {
rho: 0.85,
sigma0: 0.01,
drift_threshold: 0.05,
slew_threshold: 0.5,
min_dwell_seconds: 1.0,
},
MotifClass::CacheCollapse => Self {
rho: 0.9,
sigma0: 0.02,
drift_threshold: 0.10,
slew_threshold: 0.30,
min_dwell_seconds: 5.0,
},
MotifClass::WorkloadPhaseTransition => Self {
rho: 0.9,
sigma0: 0.02,
drift_threshold: 0.15,
slew_threshold: 0.35,
min_dwell_seconds: 30.0,
},
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct MotifGrammar {
pub plan_regression_onset: MotifParams,
pub cardinality_mismatch_regime: MotifParams,
pub contention_ramp: MotifParams,
pub cache_collapse: MotifParams,
pub workload_phase_transition: MotifParams,
}
impl Default for MotifGrammar {
fn default() -> Self {
Self {
plan_regression_onset: MotifParams::default_for(MotifClass::PlanRegressionOnset),
cardinality_mismatch_regime: MotifParams::default_for(
MotifClass::CardinalityMismatchRegime,
),
contention_ramp: MotifParams::default_for(MotifClass::ContentionRamp),
cache_collapse: MotifParams::default_for(MotifClass::CacheCollapse),
workload_phase_transition: MotifParams::default_for(
MotifClass::WorkloadPhaseTransition,
),
}
}
}
impl MotifGrammar {
pub fn params(&self, class: MotifClass) -> &MotifParams {
match class {
MotifClass::PlanRegressionOnset => &self.plan_regression_onset,
MotifClass::CardinalityMismatchRegime => &self.cardinality_mismatch_regime,
MotifClass::ContentionRamp => &self.contention_ramp,
MotifClass::CacheCollapse => &self.cache_collapse,
MotifClass::WorkloadPhaseTransition => &self.workload_phase_transition,
}
}
pub fn from_yaml(yaml: &str) -> anyhow::Result<Self> {
Ok(serde_yaml::from_str(yaml)?)
}
}
pub struct MotifEngine {
grammar: MotifGrammar,
}
impl MotifEngine {
pub fn new(grammar: MotifGrammar) -> Self {
Self { grammar }
}
pub fn run(&self, stream: &ResidualStream) -> Vec<Episode> {
let mut all = Vec::new();
for class in MotifClass::ALL {
let params = self.grammar.params(class).clone();
let eps = motifs::run_motif(class, ¶ms, stream);
all.extend(eps);
}
all.sort_by(|a, b| {
a.t_start
.partial_cmp(&b.t_start)
.unwrap_or(std::cmp::Ordering::Equal)
});
all
}
}