use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub enum BenchPath {
QueryBuild,
Pool,
Cache,
Transaction,
Serialization,
Stream,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct BaselinePoint {
pub path: BenchPath,
pub name: String,
pub mean_ns: f64,
pub stddev_ns: f64,
pub p99_ns: f64,
pub timestamp: u64,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RegressionPoint {
pub path: BenchPath,
pub name: String,
pub current_mean_ns: f64,
pub baseline_mean_ns: f64,
pub change_percent: f64,
pub is_regression: bool,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RegressionReport {
pub timestamp: u64,
pub points: Vec<RegressionPoint>,
pub regression_count: usize,
pub improvement_count: usize,
}
impl RegressionReport {
pub fn from_points(points: Vec<RegressionPoint>) -> Self {
let regression_count = points
.iter()
.filter(|p| p.is_regression && p.change_percent > 0.0)
.count();
let improvement_count = points.iter().filter(|p| p.change_percent < 0.0).count();
Self {
timestamp: std::time::SystemTime::now()
.duration_since(std::time::UNIX_EPOCH)
.unwrap_or_default()
.as_secs(),
points,
regression_count,
improvement_count,
}
}
}
pub fn compute_change(current: f64, baseline: f64) -> (f64, bool) {
if baseline == 0.0 {
return (0.0, false);
}
let change_percent = ((current - baseline) / baseline) * 100.0;
let is_regression = change_percent.abs() >= 10.0;
(change_percent, is_regression)
}