Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file modified crates/before-fuelscape/dump/atlas.json.gz
Binary file not shown.
Binary file modified crates/before-fuelscape/dump/ceiling_contains.json.gz
Binary file not shown.
Binary file modified crates/before-fuelscape/dump/clock_decode.json.gz
Binary file not shown.
Binary file modified crates/before-fuelscape/dump/clock_display.json.gz
Binary file not shown.
Binary file modified crates/before-fuelscape/dump/clock_encode.json.gz
Binary file not shown.
Binary file modified crates/before-fuelscape/dump/clock_fork.json.gz
Binary file not shown.
Binary file modified crates/before-fuelscape/dump/clock_forks.json.gz
Binary file not shown.
Binary file modified crates/before-fuelscape/dump/clock_from_parts.json.gz
Binary file not shown.
Binary file modified crates/before-fuelscape/dump/clock_fromstr.json.gz
Binary file not shown.
Binary file modified crates/before-fuelscape/dump/clock_into_parts.json.gz
Binary file not shown.
Binary file modified crates/before-fuelscape/dump/clock_join.json.gz
Binary file not shown.
Binary file modified crates/before-fuelscape/dump/clock_join_all.json.gz
Binary file not shown.
Binary file modified crates/before-fuelscape/dump/clock_own_version.json.gz
Binary file not shown.
Binary file modified crates/before-fuelscape/dump/clock_recv.json.gz
Binary file not shown.
Binary file modified crates/before-fuelscape/dump/clock_recv_all.json.gz
Binary file not shown.
Binary file modified crates/before-fuelscape/dump/clock_send.json.gz
Binary file not shown.
Binary file added crates/before-fuelscape/dump/clock_shape.json.gz
Binary file not shown.
Binary file modified crates/before-fuelscape/dump/clock_sync.json.gz
Binary file not shown.
Binary file modified crates/before-fuelscape/dump/clock_sync_all.json.gz
Binary file not shown.
Binary file modified crates/before-fuelscape/dump/clock_tick.json.gz
Binary file not shown.
Binary file modified crates/before-fuelscape/dump/floor_contains.json.gz
Binary file not shown.
Binary file modified crates/before-fuelscape/dump/own_span_contains.json.gz
Binary file not shown.
Binary file modified crates/before-fuelscape/dump/own_span_dominance.json.gz
Binary file not shown.
Binary file modified crates/before-fuelscape/dump/own_span_place.json.gz
Binary file not shown.
Binary file modified crates/before-fuelscape/dump/own_span_precedence.json.gz
Binary file not shown.
Binary file modified crates/before-fuelscape/dump/own_version_cmp.json.gz
Binary file not shown.
Binary file modified crates/before-fuelscape/dump/own_version_pair_cmp.json.gz
Binary file not shown.
Binary file modified crates/before-fuelscape/dump/party_covers.json.gz
Binary file not shown.
Binary file modified crates/before-fuelscape/dump/party_decode.json.gz
Binary file not shown.
Binary file modified crates/before-fuelscape/dump/party_display.json.gz
Binary file not shown.
Binary file modified crates/before-fuelscape/dump/party_encode.json.gz
Binary file not shown.
Binary file modified crates/before-fuelscape/dump/party_fork.json.gz
Binary file not shown.
Binary file modified crates/before-fuelscape/dump/party_forks.json.gz
Binary file not shown.
Binary file modified crates/before-fuelscape/dump/party_fromstr.json.gz
Binary file not shown.
Binary file modified crates/before-fuelscape/dump/party_hash.json.gz
Binary file not shown.
Binary file modified crates/before-fuelscape/dump/party_is_disjoint.json.gz
Binary file not shown.
Binary file modified crates/before-fuelscape/dump/party_join.json.gz
Binary file not shown.
Binary file modified crates/before-fuelscape/dump/party_join_all.json.gz
Binary file not shown.
Binary file added crates/before-fuelscape/dump/party_shape.json.gz
Binary file not shown.
Binary file modified crates/before-fuelscape/dump/party_without.json.gz
Binary file not shown.
Binary file not shown.
Binary file modified crates/before-fuelscape/dump/query_conjoin_ceilings.json.gz
Binary file not shown.
Binary file modified crates/before-fuelscape/dump/query_conjoin_floors.json.gz
Binary file not shown.
Binary file modified crates/before-fuelscape/dump/query_contains_ceiling.json.gz
Binary file not shown.
Binary file modified crates/before-fuelscape/dump/query_contains_ceiling_hole.json.gz
Binary file not shown.
Binary file modified crates/before-fuelscape/dump/query_contains_floor.json.gz
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file modified crates/before-fuelscape/dump/query_contains_floor_hole.json.gz
Binary file not shown.
Binary file modified crates/before-fuelscape/dump/query_contains_hole.json.gz
Binary file not shown.
Binary file modified crates/before-fuelscape/dump/query_coverage_ceiling.json.gz
Binary file not shown.
Binary file modified crates/before-fuelscape/dump/query_coverage_ceiling_hole.json.gz
Binary file not shown.
Binary file modified crates/before-fuelscape/dump/query_coverage_floor.json.gz
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file modified crates/before-fuelscape/dump/query_coverage_floor_hole.json.gz
Binary file not shown.
Binary file modified crates/before-fuelscape/dump/query_coverage_hole.json.gz
Binary file not shown.
Binary file modified crates/before-fuelscape/dump/rank_add.json.gz
Binary file not shown.
Binary file modified crates/before-fuelscape/dump/rank_checked_sub.json.gz
Binary file not shown.
Binary file modified crates/before-fuelscape/dump/rank_cmp.json.gz
Binary file not shown.
Binary file modified crates/before-fuelscape/dump/rank_decode.json.gz
Binary file not shown.
Binary file modified crates/before-fuelscape/dump/rank_display.json.gz
Binary file not shown.
Binary file modified crates/before-fuelscape/dump/rank_encode.json.gz
Binary file not shown.
Binary file modified crates/before-fuelscape/dump/ranked_cmp.json.gz
Binary file not shown.
Binary file modified crates/before-fuelscape/dump/ranked_decode.json.gz
Binary file not shown.
Binary file modified crates/before-fuelscape/dump/ranked_encode.json.gz
Binary file not shown.
Binary file modified crates/before-fuelscape/dump/ranked_encode_rank.json.gz
Binary file not shown.
Binary file not shown.
Binary file modified crates/before-fuelscape/dump/span_contains.json.gz
Binary file not shown.
Binary file modified crates/before-fuelscape/dump/span_decode.json.gz
Binary file not shown.
Binary file modified crates/before-fuelscape/dump/span_dominance.json.gz
Binary file not shown.
Binary file modified crates/before-fuelscape/dump/span_encode.json.gz
Binary file not shown.
Binary file modified crates/before-fuelscape/dump/span_intersect.json.gz
Binary file not shown.
Binary file modified crates/before-fuelscape/dump/span_intersect_all.json.gz
Binary file not shown.
Binary file modified crates/before-fuelscape/dump/span_join.json.gz
Binary file not shown.
Binary file modified crates/before-fuelscape/dump/span_join_all.json.gz
Binary file not shown.
Binary file modified crates/before-fuelscape/dump/span_meet.json.gz
Binary file not shown.
Binary file modified crates/before-fuelscape/dump/span_meet_all.json.gz
Binary file not shown.
Binary file modified crates/before-fuelscape/dump/span_place.json.gz
Binary file not shown.
Binary file modified crates/before-fuelscape/dump/span_precedence.json.gz
Binary file not shown.
Binary file modified crates/before-fuelscape/dump/span_project.json.gz
Binary file not shown.
Binary file modified crates/before-fuelscape/dump/span_union.json.gz
Binary file not shown.
Binary file modified crates/before-fuelscape/dump/span_union_all.json.gz
Binary file not shown.
Binary file modified crates/before-fuelscape/dump/version_cmp.json.gz
Binary file not shown.
Binary file modified crates/before-fuelscape/dump/version_concurrent.json.gz
Binary file not shown.
Binary file modified crates/before-fuelscape/dump/version_decode.json.gz
Binary file not shown.
Binary file modified crates/before-fuelscape/dump/version_display.json.gz
Binary file not shown.
Binary file modified crates/before-fuelscape/dump/version_distance.json.gz
Binary file not shown.
Binary file modified crates/before-fuelscape/dump/version_encode.json.gz
Binary file not shown.
Binary file modified crates/before-fuelscape/dump/version_eq.json.gz
Binary file not shown.
Binary file modified crates/before-fuelscape/dump/version_fromstr.json.gz
Binary file not shown.
Binary file modified crates/before-fuelscape/dump/version_hash.json.gz
Binary file not shown.
Binary file modified crates/before-fuelscape/dump/version_join.json.gz
Binary file not shown.
Binary file modified crates/before-fuelscape/dump/version_join_all.json.gz
Binary file not shown.
Binary file modified crates/before-fuelscape/dump/version_lag.json.gz
Binary file not shown.
Binary file modified crates/before-fuelscape/dump/version_meet.json.gz
Binary file not shown.
Binary file modified crates/before-fuelscape/dump/version_meet_all.json.gz
Binary file not shown.
Binary file modified crates/before-fuelscape/dump/version_min_ticks.json.gz
Binary file not shown.
Binary file modified crates/before-fuelscape/dump/version_project.json.gz
Binary file not shown.
Binary file modified crates/before-fuelscape/dump/version_rank.json.gz
Binary file not shown.
Binary file not shown.
Binary file modified crates/before-fuelscape/dump/version_span.json.gz
Binary file not shown.
Binary file modified crates/before-fuelscape/dump/version_span_all.json.gz
Binary file not shown.
Binary file modified crates/before-fuelscape/dump/version_tick.json.gz
Binary file not shown.
Binary file modified crates/before-fuelscape/dump/version_ticks.json.gz
Binary file not shown.
13 changes: 7 additions & 6 deletions crates/before-fuelscape/src/bin/fuelscape.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ static ALLOC: mimalloc::MiMalloc = mimalloc::MiMalloc;

use before_fuelscape::ops::ROSTER;
use before_fuelscape::plan::{run_op_with_progress, Plan, Samplers};
use before_fuelscape::render::{render_gallery, render_op, AtlasData, RenderMeta};
use before_fuelscape::render::{render_gallery, render_op, AtlasData, RenderMeta, RunParams};
use before_fuelscape::select::{listing, select};
use fuzzfit_harness::wasm::Guest;
use indicatif::{MultiProgress, ProgressBar, ProgressStyle};
Expand Down Expand Up @@ -291,17 +291,18 @@ fn main() {
.into_iter()
.map(|slot| slot.expect("every selected row ran"))
.collect();
let gallery = render_gallery(&rendered, &meta, &out).expect("gallery must render");
let gallery =
render_gallery(&rendered, &RunParams::from(&meta), &out).expect("gallery must render");
println!("gallery → {}", gallery.display());
}

/// Replay rendering from a dump: no guest, no count tables, no sampling.
fn render_from_dump(dump_path: &Path, out: &Path, font_scale: f64) {
let (meta, atlases) = dump::read(dump_path).expect("dump must load");
let (params, atlases) = dump::read(dump_path).expect("dump must load");
std::fs::create_dir_all(out).expect("output directory must be creatable");
let mut rendered = Vec::new();
for data in &atlases {
let path = render_op(data, &meta, out, font_scale).expect("render must succeed");
for (meta, data) in &atlases {
let path = render_op(data, meta, out, font_scale).expect("render must succeed");
println!(
"{}: {} samples, {} overlay points → {}",
data.op_name,
Expand All @@ -311,6 +312,6 @@ fn render_from_dump(dump_path: &Path, out: &Path, font_scale: f64) {
);
rendered.push((data.op_name.clone(), path));
}
let gallery = render_gallery(&rendered, &meta, out).expect("gallery must render");
let gallery = render_gallery(&rendered, &params, out).expect("gallery must render");
println!("gallery → {}", gallery.display());
}
58 changes: 36 additions & 22 deletions crates/before-fuelscape/src/compact.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ use std::path::Path;
use serde::{Deserialize, Serialize};

use crate::dump;
use crate::render::{AtlasData, OverlayData, RenderMeta};
use crate::render::{AtlasData, OverlayData, RenderMeta, RunParams};

#[cfg(test)]
mod tests;
Expand All @@ -74,7 +74,12 @@ const INDEX_FORMAT: &str = "fuelscape-widget-index";
const OP_FORMAT: &str = "fuelscape-widget-data";

/// The compact format version both banners carry.
const FORMAT_VERSION: u32 = 2;
///
/// Version 3 moved the measurement commit from the index into each
/// operation document, mirroring the dump format: a dataset accretes
/// across measuring runs, so the index holds only the run parameters
/// every document must share.
const FORMAT_VERSION: u32 = 3;

/// Histogram resolution: octaves of fuel per bin.
///
Expand All @@ -92,8 +97,9 @@ struct IndexDoc {
format: String,
/// Always [`FORMAT_VERSION`].
version: u32,
/// The measuring run's provenance, identical in every file.
meta: RenderMeta,
/// The run parameters, identical in every file; each operation
/// document carries its own measurement commit.
meta: RunParams,
/// Operation names in the dump's order; one `<name>.json` per entry.
ops: Vec<String>,
}
Expand All @@ -106,7 +112,8 @@ struct OpDoc {
format: String,
/// Always [`FORMAT_VERSION`].
version: u32,
/// The measuring run's provenance, identical in every file.
/// The measuring run's provenance: its commit, and the run
/// parameters (which must match the index's).
meta: RenderMeta,
/// The operation's compact render input.
op: WidgetOp,
Expand Down Expand Up @@ -234,9 +241,9 @@ pub fn compact(
/// Any dump-loading failure, a dump operation missing from the roster,
/// a `size_measure` disagreement, and any I/O failure writing `out`.
pub fn compact_dump(dump_path: &Path, out: &Path) -> io::Result<Vec<String>> {
let (meta, atlases) = dump::read(dump_path)?;
let (params, atlases) = dump::read(dump_path)?;
let mut ops = Vec::with_capacity(atlases.len());
for data in &atlases {
for (meta, data) in &atlases {
let spec = crate::ops::ROSTER
.iter()
.find(|spec| spec.name == data.op_name)
Expand All @@ -262,17 +269,20 @@ pub fn compact_dump(dump_path: &Path, out: &Path) -> io::Result<Vec<String>> {
),
));
}
ops.push(compact(data, spec.variant, spec.contract, spec.claim)?);
ops.push((
meta.clone(),
compact(data, spec.variant, spec.contract, spec.claim)?,
));
}
write(out, &meta, &ops)?;
Ok(ops.into_iter().map(|op| op.op_name).collect())
write(out, &params, &ops)?;
Ok(ops.into_iter().map(|(_, op)| op.op_name).collect())
}

/// Write a compact dataset: every operation document, then the index,
/// each atomically.
pub fn write(dir: &Path, meta: &RenderMeta, ops: &[WidgetOp]) -> io::Result<()> {
/// Write a compact dataset: every operation document (each with its own
/// measurement provenance), then the index, each atomically.
pub fn write(dir: &Path, params: &RunParams, ops: &[(RenderMeta, WidgetOp)]) -> io::Result<()> {
std::fs::create_dir_all(dir)?;
for op in ops {
for (meta, op) in ops {
let doc = OpDoc {
format: OP_FORMAT.to_string(),
version: FORMAT_VERSION,
Expand All @@ -289,15 +299,16 @@ pub fn write(dir: &Path, meta: &RenderMeta, ops: &[WidgetOp]) -> io::Result<()>
let index = IndexDoc {
format: INDEX_FORMAT.to_string(),
version: FORMAT_VERSION,
meta: meta.clone(),
ops: ops.iter().map(|op| op.op_name.clone()).collect(),
meta: params.clone(),
ops: ops.iter().map(|(_, op)| op.op_name.clone()).collect(),
};
// Pretty for the index: it is the file an operator opens.
dump::write_atomic(&dir.join(INDEX_FILE), &serde_json::to_vec_pretty(&index)?)
}

/// Load a whole compact dataset: the measuring run's provenance and
/// every operation's widget data, in the index's order.
/// Load a whole compact dataset: the shared run parameters and every
/// operation's widget data with its own measurement provenance, in the
/// index's order.
///
/// `path` names the dataset: its `index.json` or the directory holding
/// it.
Expand All @@ -306,7 +317,7 @@ pub fn write(dir: &Path, meta: &RenderMeta, ops: &[WidgetOp]) -> io::Result<()>
///
/// Any I/O failure, and every strictness rejection the module doc
/// enumerates; the error message names the offending file and check.
pub fn read(path: &Path) -> io::Result<(RenderMeta, Vec<WidgetOp>)> {
pub fn read(path: &Path) -> io::Result<(RunParams, Vec<(RenderMeta, WidgetOp)>)> {
let index_path = if path.is_dir() {
path.join(INDEX_FILE)
} else {
Expand Down Expand Up @@ -342,8 +353,11 @@ pub fn read(path: &Path) -> io::Result<(RenderMeta, Vec<WidgetOp>)> {
doc.version,
FORMAT_VERSION,
)?;
if doc.meta != index.meta {
return Err(dump::malformed(&op_path, "meta differs from the index's"));
if RunParams::from(&doc.meta) != index.meta {
return Err(dump::malformed(
&op_path,
"run parameters differ from the index's",
));
}
if doc.op.op_name != *name {
return Err(dump::malformed(
Expand All @@ -355,7 +369,7 @@ pub fn read(path: &Path) -> io::Result<(RenderMeta, Vec<WidgetOp>)> {
));
}
validate(&op_path, &doc.op)?;
ops.push(doc.op);
ops.push((doc.meta, doc.op));
}
Ok((index.meta, ops))
}
Expand Down
38 changes: 23 additions & 15 deletions crates/before-fuelscape/src/compact/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use std::path::Path;

use crate::dump::DumpWriter;
use crate::ops::ROSTER;
use crate::render::{AtlasData, OverlayData, RenderMeta, SampleData};
use crate::render::{AtlasData, OverlayData, RenderMeta, RunParams, SampleData};

use super::{compact, compact_dump, read, write, WidgetCol, RES};

Expand Down Expand Up @@ -104,10 +104,18 @@ fn dataset_round_trips_losslessly() {
"n log n",
)
.expect("synthetic atlas compacts");
write(&dir, &meta(), std::slice::from_ref(&op)).expect("dataset writes");
let (loaded_meta, loaded) = read(&dir).expect("dataset loads");
assert_eq!(loaded_meta, meta(), "meta round-trips exactly");
assert_eq!(loaded, vec![op], "the widget data round-trips exactly");
write(&dir, &RunParams::from(&meta()), &[(meta(), op.clone())]).expect("dataset writes");
let (loaded_params, loaded) = read(&dir).expect("dataset loads");
assert_eq!(
loaded_params,
RunParams::from(&meta()),
"the run parameters round-trip exactly"
);
assert_eq!(
loaded,
vec![(meta(), op)],
"the provenance and widget data round-trip exactly"
);
std::fs::remove_dir_all(&dir).expect("round-trip output cleans up");
}

Expand All @@ -133,7 +141,7 @@ fn compaction_rejects_zero_fuel() {
fn read_rejects_each_tampered_document() {
let dir = temp_dir("tamper");
let op = compact(&synthetic_atlas(), "", "`O(1)`.", "1").expect("synthetic atlas compacts");
write(&dir, &meta(), std::slice::from_ref(&op)).expect("dataset writes");
write(&dir, &RunParams::from(&meta()), &[(meta(), op)]).expect("dataset writes");
let op_path = dir.join("synthetic.json");
let pristine = std::fs::read(&op_path).expect("op file exists");

Expand Down Expand Up @@ -161,7 +169,7 @@ fn read_rejects_each_tampered_document() {
&|doc| doc["format"] = "fuelscape-atlas-index".into(),
"format",
);
tamper(&|doc| doc["meta"]["base_seed"] = 7.into(), "meta");
tamper(&|doc| doc["meta"]["base_seed"] = 7.into(), "run parameters");
tamper(&|doc| doc["op"]["claim"] = "".into(), "non-empty");
tamper(&|doc| doc["op"]["res"] = 0.0.into(), "resolution");
tamper(
Expand All @@ -184,8 +192,8 @@ fn read_rejects_each_tampered_document() {
fn gzipped_documents_read_transparently() {
let dir = temp_dir("gz");
let op = compact(&synthetic_atlas(), "", "`O(1)`.", "1").expect("synthetic atlas compacts");
write(&dir, &meta(), std::slice::from_ref(&op)).expect("dataset writes");
let (plain_meta, plain_ops) = read(&dir).expect("plain dataset loads");
write(&dir, &RunParams::from(&meta()), &[(meta(), op)]).expect("dataset writes");
let (plain_params, plain_ops) = read(&dir).expect("plain dataset loads");
for name in ["synthetic.json", super::INDEX_FILE] {
let path = dir.join(name);
let bytes = std::fs::read(&path).expect("document exists");
Expand All @@ -196,10 +204,10 @@ fn gzipped_documents_read_transparently() {
std::fs::write(gz_path, gz.finish().expect("gzip finishes")).expect("gz file writes");
std::fs::remove_file(&path).expect("plain file removes");
}
let (gz_meta, gz_ops) = read(&dir).expect("gzipped dataset loads");
let (gz_params, gz_ops) = read(&dir).expect("gzipped dataset loads");
assert_eq!(
(gz_meta, gz_ops),
(plain_meta, plain_ops),
(gz_params, gz_ops),
(plain_params, plain_ops),
"gz and plain forms load equal"
);
std::fs::remove_dir_all(&dir).expect("gz output cleans up");
Expand Down Expand Up @@ -230,15 +238,15 @@ fn compact_dump_joins_the_roster_and_rejects_measure_drift() {
compact_dump(&dump_dir, &out_dir).expect("a roster-matched dump compacts");
let (_, ops) = read(&out_dir).expect("compacted dataset loads");
assert_eq!(
ops[0].variant, spec.variant,
ops[0].1.variant, spec.variant,
"the roster row's variant is stamped"
);
assert_eq!(
ops[0].contract, spec.contract,
ops[0].1.contract, spec.contract,
"the roster row's contract is stamped"
);
assert_eq!(
ops[0].claim, spec.claim,
ops[0].1.claim, spec.claim,
"the roster row's claim is stamped"
);

Expand Down
33 changes: 21 additions & 12 deletions crates/before-fuelscape/src/dump.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ use std::path::{Path, PathBuf};

use serde::{Deserialize, Serialize};

use crate::render::{aggregate, AtlasData, HeatGrid, RenderMeta};
use crate::render::{aggregate, AtlasData, HeatGrid, RenderMeta, RunParams};

#[cfg(test)]
mod tests;
Expand All @@ -63,7 +63,11 @@ const INDEX_FORMAT: &str = "fuelscape-atlas-index";
const OP_FORMAT: &str = "fuelscape-op-atlas";

/// The dump format version both banners carry.
const FORMAT_VERSION: u32 = 1;
///
/// Version 2 moved the measurement commit from the index into each
/// operation document: a dataset accretes across measuring runs, so the
/// index holds only the run parameters every document must share.
const FORMAT_VERSION: u32 = 2;

/// The index document: run provenance plus the ordered operation list.
#[derive(Serialize, Deserialize)]
Expand All @@ -73,8 +77,9 @@ struct IndexDoc {
format: String,
/// Always [`FORMAT_VERSION`].
version: u32,
/// The run's provenance, identical in every file of the dump.
meta: RenderMeta,
/// The run parameters, identical in every file of the dump; each
/// operation document carries its own measurement commit.
meta: RunParams,
/// Operation names in measuring order (the gallery's order); one
/// `<name>.json` per entry.
ops: Vec<String>,
Expand All @@ -88,7 +93,8 @@ struct OpDoc {
format: String,
/// Always [`FORMAT_VERSION`].
version: u32,
/// The run's provenance, identical in every file of the dump.
/// The measuring run's provenance: its commit, and the run
/// parameters (which must match the index's).
meta: RenderMeta,
/// The operation's complete render input.
op: AtlasData,
Expand Down Expand Up @@ -147,7 +153,7 @@ impl DumpWriter {
let doc = IndexDoc {
format: INDEX_FORMAT.to_string(),
version: FORMAT_VERSION,
meta: self.meta.clone(),
meta: RunParams::from(&self.meta),
ops: self.ops.clone(),
};
// Pretty for the index: it is small, and it is the file an
Expand All @@ -168,16 +174,16 @@ pub(crate) fn write_atomic(path: &Path, bytes: &[u8]) -> io::Result<()> {
std::fs::rename(&tmp, path)
}

/// Load a whole dump: the run's provenance and every operation's atlas,
/// in the index's order.
/// Load a whole dump: the shared run parameters and every operation's
/// atlas with its own measurement provenance, in the index's order.
///
/// `path` names the dump: its `atlas.json` or the directory holding it.
///
/// # Errors
///
/// Any I/O failure, and every strictness rejection the module doc
/// enumerates; the error message names the offending file and check.
pub fn read(path: &Path) -> io::Result<(RenderMeta, Vec<AtlasData>)> {
pub fn read(path: &Path) -> io::Result<(RunParams, Vec<(RenderMeta, AtlasData)>)> {
let index_path = if path.is_dir() {
path.join(INDEX_FILE)
} else {
Expand Down Expand Up @@ -210,8 +216,11 @@ pub fn read(path: &Path) -> io::Result<(RenderMeta, Vec<AtlasData>)> {
doc.version,
FORMAT_VERSION,
)?;
if doc.meta != index.meta {
return Err(malformed(&op_path, "meta differs from the index's"));
if RunParams::from(&doc.meta) != index.meta {
return Err(malformed(
&op_path,
"run parameters differ from the index's",
));
}
if doc.op.op_name != *name {
return Err(malformed(
Expand All @@ -232,7 +241,7 @@ pub fn read(path: &Path) -> io::Result<(RenderMeta, Vec<AtlasData>)> {
(the dump was altered, or it predates a change to the aggregation)",
));
}
atlases.push(doc.op);
atlases.push((doc.meta, doc.op));
}
Ok((index.meta, atlases))
}
Expand Down
Loading