use super::{
BenchAttachment, BenchBinding, BenchBindingRefusal, BenchInvocation, BenchOutcome,
BenchReading, BenchReport, BenchRow, BenchRowKey, BenchStage, BenchTable, BenchTableName,
BenchTableRefusal, BenchVerdictRefusal, ContentionPosture, PreflightRef, PreflightTrial,
};
use crate::clock::HarnessClock;
use crate::descriptor::Provenance;
use crate::report::{TargetBinding, TrialReport};
use crate::runner::{Invocation, TrialBinding};
use std::collections::BTreeMap;
impl PreflightTrial {
#[must_use]
pub fn bound(reference: PreflightRef, binding: TrialBinding, invocation: Invocation) -> Self {
Self {
reference,
binding,
invocation,
}
}
#[must_use]
pub const fn reference(&self) -> PreflightRef {
self.reference
}
#[must_use]
pub const fn binding(&self) -> &TrialBinding {
&self.binding
}
#[must_use]
pub const fn invocation(&self) -> &Invocation {
&self.invocation
}
}
impl BenchBinding {
pub fn bound(
row: BenchRow,
attachment: BenchAttachment,
preflight: PreflightTrial,
) -> Result<Self, BenchBindingRefusal> {
if row.workload() != attachment.workload() {
return Err(BenchBindingRefusal::Workload {
row: row.workload(),
attachment: attachment.workload(),
});
}
if row.planted_worse() != attachment.planted_worse_ref() {
return Err(BenchBindingRefusal::PlantedWorse {
row: row.planted_worse(),
attachment: attachment.planted_worse_ref(),
});
}
if row.preflight() != preflight.reference() {
return Err(BenchBindingRefusal::Preflight {
row: row.preflight(),
trial: preflight.reference(),
});
}
if row.complexity() != attachment.judge().complexity() {
return Err(BenchBindingRefusal::Complexity {
row: row.complexity(),
judge: attachment.judge().complexity(),
});
}
Ok(Self {
row,
attachment,
preflight,
})
}
#[must_use]
pub const fn row(&self) -> &BenchRow {
&self.row
}
#[must_use]
pub const fn attachment(&self) -> &BenchAttachment {
&self.attachment
}
#[must_use]
pub const fn preflight(&self) -> &PreflightTrial {
&self.preflight
}
}
impl BenchTable {
pub fn authored(
name: BenchTableName,
provenance: Provenance,
bindings: Vec<BenchBinding>,
) -> Result<Self, BenchTableRefusal> {
if bindings.is_empty() {
return Err(BenchTableRefusal::Empty);
}
let mut seen = BTreeMap::new();
for (duplicate, binding) in bindings.iter().enumerate() {
let row = binding.row().key();
if let Some(first) = seen.insert(row, duplicate) {
return Err(BenchTableRefusal::DuplicateRow {
row,
first,
duplicate,
});
}
}
Ok(Self {
name,
provenance,
bindings,
})
}
#[must_use]
pub const fn name(&self) -> BenchTableName {
self.name
}
#[must_use]
pub const fn provenance(&self) -> Provenance {
self.provenance
}
#[must_use]
pub fn bindings(&self) -> &[BenchBinding] {
&self.bindings
}
#[must_use]
pub fn len(&self) -> usize {
self.bindings.len()
}
#[must_use]
pub fn is_empty(&self) -> bool {
self.bindings.is_empty()
}
}
impl BenchInvocation {
#[must_use]
pub fn declared(
target: TargetBinding,
clock: HarnessClock,
contention: ContentionPosture,
) -> Self {
Self {
target,
clock,
contention,
}
}
#[must_use]
pub const fn target(&self) -> &TargetBinding {
&self.target
}
#[must_use]
pub const fn clock(&self) -> HarnessClock {
self.clock
}
#[must_use]
pub const fn contention(&self) -> ContentionPosture {
self.contention
}
}
impl BenchOutcome {
#[must_use]
pub const fn stage(&self) -> BenchStage {
match self {
Self::PreflightRefused => BenchStage::PreflightRefused,
Self::PlantedWorseNotDistinguished { .. } => BenchStage::PlantedWorseNotDistinguished,
Self::PrimaryWorkRefused { .. } => BenchStage::PrimaryWorkRefused,
Self::Qualified { .. } => BenchStage::Qualified,
}
}
}
impl BenchReading {
pub(in crate::bench) fn recorded(
row: &BenchRow,
target: TargetBinding,
preflight: TrialReport,
outcome: BenchOutcome,
) -> Self {
Self {
row: row.clone(),
target,
preflight,
outcome,
}
}
#[must_use]
pub const fn row(&self) -> &BenchRow {
&self.row
}
#[must_use]
pub const fn target(&self) -> &TargetBinding {
&self.target
}
#[must_use]
pub const fn preflight(&self) -> &TrialReport {
&self.preflight
}
#[must_use]
pub const fn outcome(&self) -> &BenchOutcome {
&self.outcome
}
}
impl BenchReport {
pub(in crate::bench) fn recorded(
table: BenchTableName,
provenance: Provenance,
readings: Vec<BenchReading>,
) -> Self {
Self {
table,
provenance,
readings,
}
}
#[must_use]
pub const fn table(&self) -> BenchTableName {
self.table
}
#[must_use]
pub const fn provenance(&self) -> Provenance {
self.provenance
}
#[must_use]
pub fn readings(&self) -> &[BenchReading] {
&self.readings
}
#[must_use]
pub fn denominator(&self) -> usize {
self.readings.len()
}
}
impl BenchVerdictRefusal {
pub(in crate::bench) const fn row_not_qualified(row: BenchRowKey, stage: BenchStage) -> Self {
Self { row, stage }
}
#[must_use]
pub const fn row(self) -> BenchRowKey {
self.row
}
#[must_use]
pub const fn stage(self) -> BenchStage {
self.stage
}
}