Load region fixed-row summaries into save slices

This commit is contained in:
Jan Petykiewicz 2026-04-19 03:31:20 -07:00
commit 1f305222b8
5 changed files with 279 additions and 14 deletions

View file

@ -1792,6 +1792,17 @@ pub struct SmpLoadedRegionCollection {
pub entries: Vec<SmpLoadedRegionEntry>,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct SmpLoadedRegionFixedRowRunSummary {
pub source_kind: String,
pub semantic_family: String,
pub target_row_count: usize,
pub target_row_stride: usize,
pub target_row_stride_hex: String,
#[serde(default)]
pub candidates: Vec<SmpSaveRegionFixedRowRunCandidate>,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct SmpSaveRegionQueuedNoticeRecordEntryProbe {
pub node_base_offset: usize,
@ -4131,6 +4142,8 @@ pub struct SmpLoadedSaveSlice {
#[serde(default)]
pub region_collection: Option<SmpLoadedRegionCollection>,
#[serde(default)]
pub region_fixed_row_run_summary: Option<SmpLoadedRegionFixedRowRunSummary>,
#[serde(default)]
pub placed_structure_collection: Option<SmpLoadedPlacedStructureCollection>,
#[serde(default)]
pub placed_structure_dynamic_side_buffer_summary:
@ -6997,6 +7010,19 @@ fn derive_loaded_region_collection_from_probe(
}
}
fn derive_loaded_region_fixed_row_run_summary_from_probe(
probe: &SmpSaveRegionFixedRowRunCandidateProbe,
) -> SmpLoadedRegionFixedRowRunSummary {
SmpLoadedRegionFixedRowRunSummary {
source_kind: probe.source_kind.clone(),
semantic_family: "scenario-save-region-fixed-row-run-summary".to_string(),
target_row_count: probe.target_row_count,
target_row_stride: probe.target_row_stride,
target_row_stride_hex: probe.target_row_stride_hex.clone(),
candidates: probe.candidates.clone(),
}
}
fn derive_loaded_placed_structure_dynamic_side_buffer_summary(
probe: &SmpSavePlacedStructureDynamicSideBufferProbe,
alignment: Option<&SmpSavePlacedStructureDynamicSideBufferAlignmentProbe>,
@ -7174,6 +7200,10 @@ pub fn load_save_slice_from_report(
.save_region_record_triplet_probe
.as_ref()
.map(derive_loaded_region_collection_from_probe);
let region_fixed_row_run_summary = report
.save_region_fixed_row_run_candidate_probe
.as_ref()
.map(derive_loaded_region_fixed_row_run_summary_from_probe);
let placed_structure_collection = report
.save_placed_structure_record_triplet_probe
.as_ref()
@ -7368,6 +7398,21 @@ pub fn load_save_slice_from_report(
nonzero_reserved_count
));
}
if let Some(summary) = &region_fixed_row_run_summary {
notes.push(format!(
"Save-slice projection now also carries the region fixed-row run summary with {} candidate row bands at target stride {}, best rows offset {:?}, and best shape signature {:?}.",
summary.candidates.len(),
summary.target_row_stride_hex,
summary
.candidates
.first()
.map(|candidate| candidate.rows_offset_hex.as_str()),
summary
.candidates
.first()
.map(|candidate| candidate.shape_signature.as_str())
));
}
if let Some(probe) = &report.save_placed_structure_collection_header_probe {
notes.push(format!(
"Raw save tagged placed-structure header reports live_record_count={} and live_id_bound={} with serialized stride hint 0x{:x} at file offsets 0x{:x}/0x{:x}/0x{:x}.",
@ -7515,6 +7560,7 @@ pub fn load_save_slice_from_report(
company_roster,
chairman_profile_table,
region_collection,
region_fixed_row_run_summary,
placed_structure_collection,
placed_structure_dynamic_side_buffer_summary,
special_conditions_table,
@ -25658,6 +25704,41 @@ mod tests {
],
evidence: vec![],
});
report.save_region_fixed_row_run_candidate_probe =
Some(SmpSaveRegionFixedRowRunCandidateProbe {
profile_family: "rt3-classic-save-container-v1".to_string(),
source_kind: "save-region-fixed-row-run-candidates".to_string(),
semantic_family: "scenario-save-region-fixed-row-run-candidates".to_string(),
target_row_count: 2,
target_row_stride: 0xbc,
target_row_stride_hex: "0xbc".to_string(),
scan_start_offset: 0x5200,
scan_start_offset_hex: "0x5200".to_string(),
scan_end_offset: 0x5600,
scan_end_offset_hex: "0x5600".to_string(),
candidates: vec![SmpSaveRegionFixedRowRunCandidate {
count_offset: 0x5300,
count_offset_hex: "0x5300".to_string(),
row_count: 2,
row_stride: 0xbc,
row_stride_hex: "0xbc".to_string(),
rows_offset: 0x5310,
rows_offset_hex: "0x5310".to_string(),
rows_end_offset: 0x5488,
rows_end_offset_hex: "0x5488".to_string(),
distance_to_region_metadata_tag: 0x110,
distance_to_region_metadata_tag_hex: "0x110".to_string(),
dword_lane_summaries: vec![],
shape_signature: "dword0:f32,dword1:zero".to_string(),
shape_family_signature: "family-a".to_string(),
trailing_byte_zero_count: 2,
trailing_byte_nonzero_count: 0,
trailing_byte_distinct_value_count: 1,
trailing_byte_sample_values_hex: vec!["0x00".to_string()],
best_probable_density_lane_relative_offset_hex: Some("0x24".to_string()),
}],
evidence: vec![],
});
report.save_placed_structure_record_triplet_probe =
Some(SmpSavePlacedStructureRecordTripletProbe {
profile_family: "rt3-classic-save-container-v1".to_string(),
@ -25839,6 +25920,18 @@ mod tests {
.map(|collection| collection.entries.len()),
Some(2)
);
let region_fixed_row_run_summary = slice
.region_fixed_row_run_summary
.expect("region fixed-row summary should project");
assert_eq!(
region_fixed_row_run_summary.source_kind,
"save-region-fixed-row-run-candidates"
);
assert_eq!(region_fixed_row_run_summary.candidates.len(), 1);
assert_eq!(
region_fixed_row_run_summary.candidates[0].rows_offset_hex,
"0x5310"
);
let collection = slice
.placed_structure_collection
.expect("placed structure collection should project");
@ -25868,6 +25961,9 @@ mod tests {
line.contains("loaded region triplet rows as first-class context")
&& line.contains("3 embedded profile rows")
}));
assert!(slice.notes.iter().any(|line| {
line.contains("region fixed-row run summary") && line.contains("Some(\"0x5310\")")
}));
assert!(slice.notes.iter().any(|line| {
line.contains("placed-structure triplet rows as first-class context")
&& line.contains("2")