sqlitegraph 2.2.2

Embedded graph database with full ACID transactions, HNSW vector search, dual backend support, and comprehensive graph algorithms library
Documentation
use std::collections::HashMap;

use crate::bench_meta::BenchRun;

#[derive(Clone, Debug, PartialEq)]
pub struct BenchGateConfig {
    pub thresholds: Vec<(String, u64)>,
    pub baseline: Vec<BenchRun>,
    pub tolerance: f64,
}

#[derive(Clone, Debug, PartialEq)]
pub enum BenchOutcome {
    Pass,
    Fail(Vec<String>),
}

#[derive(Clone, Debug)]
pub struct BenchGate {
    thresholds: HashMap<String, u64>,
    baseline: HashMap<String, BenchRun>,
    tolerance: f64,
}

impl BenchGate {
    pub fn new(config: BenchGateConfig) -> Self {
        let thresholds = config.thresholds.into_iter().collect();
        let baseline = config
            .baseline
            .into_iter()
            .map(|run| (run.name.clone(), run))
            .collect();
        Self {
            thresholds,
            baseline,
            tolerance: config.tolerance,
        }
    }

    pub fn evaluate(&self, runs: &[BenchRun]) -> BenchOutcome {
        let mut failures = Vec::new();
        for run in runs {
            if let Some(max_ns) = self.thresholds.get(&run.name)
                && !run.within_threshold(*max_ns)
            {
                failures.push(format!("{} exceeds threshold {}ns", run.name, max_ns));
            }
            if let Some(baseline) = self.baseline.get(&run.name)
                && !run.within_regression(baseline, self.tolerance)
            {
                failures.push(format!(
                    "{} regression: current={}ns baseline={}ns tolerance={}",
                    run.name, run.mean_ns, baseline.mean_ns, self.tolerance
                ));
            }
        }
        if failures.is_empty() {
            BenchOutcome::Pass
        } else {
            BenchOutcome::Fail(failures)
        }
    }
}

#[derive(Clone, Debug, PartialEq)]
pub struct GateReport {
    pub passed: bool,
    pub reasons: Vec<String>,
}

#[derive(Clone, Debug)]
pub struct GateEnforcer {
    gate: BenchGate,
}

impl GateEnforcer {
    pub fn new(gate: BenchGate) -> Self {
        Self { gate }
    }

    pub fn evaluate(&self, runs: &[BenchRun]) -> GateReport {
        match self.gate.evaluate(runs) {
            BenchOutcome::Pass => GateReport {
                passed: true,
                reasons: Vec::new(),
            },
            BenchOutcome::Fail(reasons) => GateReport {
                passed: false,
                reasons,
            },
        }
    }
}