use super::{TuneReport, TimeLimit, TuneFailure, cache::split_scoped_key, engine::SearchTrace};
use ruda_core::environment::records::{Record, RecordEffect, Span};
use serde::{Deserialize, Serialize};
use std::{string::{String, ToString}, time::Duration, vec::Vec};
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct StackTuneRecord {
pub table: String,
pub entry: String,
pub plan: Vec<String>,
pub trials: Vec<(String, Duration)>,
#[serde(default)]
pub confirmation_samples: Vec<(String, usize)>,
pub limit: Option<TimeLimit>,
pub short_circuit: Option<String>,
pub report: Option<TuneReport>,
#[serde(default)]
pub failure: Option<String>,
pub wall: Duration,
pub stored: bool,
pub dry_run: bool,
}
impl Record for StackTuneRecord { const KIND: &'static str = "stack-autotune"; }
pub(super) struct StackRecording {
span: Span,
table: String,
entry: String,
plan: Vec<String>,
dry_run: bool,
}
impl StackRecording {
pub(super) fn new<'a>(table: &str, key: &str, names: impl Iterator<Item = &'a str>) -> Option<Self> {
let (generation, entry) = split_scoped_key(key)?;
if generation != ruda_core::environment::generation() { return None; }
let span = Span::new()?;
if generation != ruda_core::environment::generation() { return None; }
Some(Self {
span, table: table.into(),
entry: entry.into(),
plan: names.map(String::from).collect(),
dry_run: crate::runtime::dry_run::dry_run(),
})
}
pub(super) fn finish(self, report: &TuneReport, trace: &SearchTrace, limit: Option<TimeLimit>, stored: bool) {
self.close(Some(report.clone()), None, trace, limit, stored);
}
pub(super) fn finish_failure(self, failure: &TuneFailure, trace: &SearchTrace, limit: Option<TimeLimit>) {
self.close(None, Some(failure.to_string()), trace, limit, false);
}
fn close(self, report: Option<TuneReport>, failure: Option<String>, trace: &SearchTrace, limit: Option<TimeLimit>, stored: bool) {
let Some(wall) = self.span.elapsed() else { return; };
let record = StackTuneRecord {
table: self.table, entry: self.entry, plan: self.plan, trials: trace.trials.clone(),
confirmation_samples: trace.confirmation_samples.clone(),
limit, short_circuit: trace.short_circuit.clone(), report, failure,
wall, stored, dry_run: self.dry_run,
};
self.span.close(if stored { RecordEffect::Changed } else { RecordEffect::Observed }, &record);
}
}