diff --git a/crates/rrt-runtime/src/smp.rs b/crates/rrt-runtime/src/smp.rs index 0d40cb1..5f5dd88 100644 --- a/crates/rrt-runtime/src/smp.rs +++ b/crates/rrt-runtime/src/smp.rs @@ -2053,6 +2053,9 @@ pub struct SmpSavePlacedStructureDynamicSideBufferFixedPolicySummary { pub dominant_trailing_word_hex: Option, pub dominant_trailing_word_count: usize, #[serde(default)] + pub compact_prefix_correlations: + Vec, + #[serde(default)] pub sample_rows: Vec, } @@ -2072,6 +2075,39 @@ pub struct SmpSavePlacedStructureDynamicSideBufferFixedPolicySample { pub trailing_word_hex: String, } +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +pub struct SmpSavePlacedStructureDynamicSideBufferFixedPolicyCompactPrefixCorrelation { + pub prefix_leading_dword: u32, + pub prefix_leading_dword_hex: String, + pub prefix_trailing_word: u16, + pub prefix_trailing_word_hex: String, + pub prefix_separator_byte: u8, + pub prefix_separator_byte_hex: String, + pub row_count: usize, + pub unique_policy_tuple_count: usize, + #[serde(default)] + pub dominant_primary_name: Option, + #[serde(default)] + pub dominant_secondary_name: Option, + pub dominant_name_pair_count: usize, + #[serde(default)] + pub dominant_mode_family: Option, + pub dominant_mode_family_count: usize, + #[serde(default)] + pub dominant_first_triplet_dwords_hex: Vec, + #[serde(default)] + pub dominant_second_triplet_dwords_hex: Vec, + #[serde(default)] + pub dominant_trailing_word: Option, + #[serde(default)] + pub dominant_trailing_word_hex: Option, + pub dominant_policy_tuple_count: usize, + #[serde(default)] + pub mode_family_counts: Vec, + #[serde(default)] + pub sample_rows: Vec, +} + #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] pub struct SmpSavePlacedStructureDynamicSideBufferShortProfileFlagPairSummary { pub row_count_with_0x06_profile_span: usize, @@ -2218,14 +2254,17 @@ pub struct SmpSavePlacedStructureDynamicSideBufferNamePreludeCompactPrefixCorrel pub dominant_mode_family: Option, pub dominant_mode_family_count: usize, #[serde(default)] - pub mode_family_counts: - Vec, + pub mode_family_counts: Vec, #[serde(default)] pub name_pair_summaries: Vec, #[serde(default)] pub profile_span_counts: Vec, + pub rows_with_previous_short_profile_flag_pair: usize, + #[serde(default)] + pub previous_short_profile_flag_pair_counts: + Vec, #[serde(default)] pub sample_rows: Vec, } @@ -2236,6 +2275,15 @@ pub struct SmpSavePlacedStructureDynamicSideBufferNamePreludeCompactPrefixProfil pub count: usize, } +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +pub struct SmpSavePlacedStructureDynamicSideBufferNamePreludeCompactPrefixFlagPairCount { + pub first_flag_byte: u8, + pub first_flag_byte_hex: String, + pub second_flag_byte: u8, + pub second_flag_byte_hex: String, + pub count: usize, +} + #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] pub struct SmpSavePlacedStructureDynamicSideBufferNamePreludeCompactPrefixSample { pub sample_index: usize, @@ -2303,8 +2351,7 @@ pub struct SmpSavePlacedStructureDynamicSideBufferNamePreludeProfileSpanCorrelat pub dominant_mode_family: Option, pub dominant_mode_family_count: usize, #[serde(default)] - pub mode_family_counts: - Vec, + pub mode_family_counts: Vec, #[serde(default)] pub compact_prefix_pattern_summaries: Vec, @@ -4582,6 +4629,76 @@ fn build_infrastructure_asset_trace_report( .map(|summary| summary.dominant_trailing_word_count) .unwrap_or_default() ), + side_buffer + .and_then(|probe| probe.payload_envelope_summary.as_ref()) + .and_then(|summary| summary.fixed_policy_summary.as_ref()) + .and_then(|summary| { + summary.compact_prefix_correlations.iter().find(|entry| { + entry.prefix_leading_dword == 0xff00_00ff + && entry.prefix_trailing_word == 0x0001 + && entry.prefix_separator_byte == 0xff + }) + }) + .map(|correlation| { + format!( + "the fixed 0x55f2 lane for exact 0xff0000ff/0x0001/0xff is now explicit too: unique policy tuples={}, dominant mode={:?} x{}, dominant tuple=({:?} | {:?} | {:?}) x{}, and sample rows={:?}", + correlation.unique_policy_tuple_count, + correlation.dominant_mode_family, + correlation.dominant_mode_family_count, + correlation.dominant_first_triplet_dwords_hex, + correlation.dominant_second_triplet_dwords_hex, + correlation.dominant_trailing_word_hex, + correlation.dominant_policy_tuple_count, + correlation + .sample_rows + .iter() + .map(|sample| format!( + "{}:{:?}/{:?}", + sample.name_tag_relative_offset, + sample.primary_name, + sample.secondary_name + )) + .collect::>() + ) + }) + .unwrap_or_else(|| { + "no fixed-policy compact-prefix correlation was available for 0xff0000ff/0x0001/0xff".to_string() + }), + side_buffer + .and_then(|probe| probe.payload_envelope_summary.as_ref()) + .and_then(|summary| summary.fixed_policy_summary.as_ref()) + .and_then(|summary| { + summary.compact_prefix_correlations.iter().find(|entry| { + entry.prefix_leading_dword == 0x0000_55f3 + && entry.prefix_trailing_word == 0x0001 + && entry.prefix_separator_byte == 0xff + }) + }) + .map(|correlation| { + format!( + "the fixed 0x55f2 lane for exact 0x000055f3/0x0001/0xff is now explicit too: unique policy tuples={}, dominant mode={:?} x{}, dominant tuple=({:?} | {:?} | {:?}) x{}, and sample rows={:?}", + correlation.unique_policy_tuple_count, + correlation.dominant_mode_family, + correlation.dominant_mode_family_count, + correlation.dominant_first_triplet_dwords_hex, + correlation.dominant_second_triplet_dwords_hex, + correlation.dominant_trailing_word_hex, + correlation.dominant_policy_tuple_count, + correlation + .sample_rows + .iter() + .map(|sample| format!( + "{}:{:?}/{:?}", + sample.name_tag_relative_offset, + sample.primary_name, + sample.secondary_name + )) + .collect::>() + ) + }) + .unwrap_or_else(|| { + "no fixed-policy compact-prefix correlation was available for 0x000055f3/0x0001/0xff".to_string() + }), side_buffer .and_then(|probe| probe.payload_envelope_summary.as_ref()) .and_then(|summary| summary.dominant_profile_span_class_summary.as_ref()) @@ -4880,7 +4997,7 @@ fn build_infrastructure_asset_trace_report( }) .map(|correlation| { format!( - "the exact 0xff0000ff/0x0001/0xff compact-prefix class is now explicit: dominant name={:?}/{:?} x{}, dominant span={:?} x{}, mode counts={:?}, name-pair counts={:?}, span counts={:?}, and sample rows={:?}", + "the exact 0xff0000ff/0x0001/0xff compact-prefix class is now explicit: dominant name={:?}/{:?} x{}, dominant span={:?} x{}, mode counts={:?}, name-pair counts={:?}, span counts={:?}, previous short-flag pairs={:?} across {} rows, and sample rows={:?}", correlation.dominant_primary_name, correlation.dominant_secondary_name, correlation.dominant_name_pair_count, @@ -4908,6 +5025,17 @@ fn build_infrastructure_asset_trace_report( entry.count )) .collect::>(), + correlation + .previous_short_profile_flag_pair_counts + .iter() + .map(|entry| format!( + "{}/{}:{}", + entry.first_flag_byte_hex, + entry.second_flag_byte_hex, + entry.count + )) + .collect::>(), + correlation.rows_with_previous_short_profile_flag_pair, correlation .sample_rows .iter() @@ -4923,6 +5051,63 @@ fn build_infrastructure_asset_trace_report( .unwrap_or_else(|| { "no grounded 0xff0000ff/0x0001/0xff compact-prefix correlation was available".to_string() }), + side_buffer + .and_then(|probe| probe.payload_envelope_summary.as_ref()) + .and_then(|summary| summary.name_prelude_candidate_summary.as_ref()) + .and_then(|summary| { + summary.compact_prefix_correlations.iter().find(|entry| { + entry.prefix_leading_dword == 0x0000_55f3 + && entry.prefix_trailing_word == 0x0001 + && entry.prefix_separator_byte == 0xff + }) + }) + .map(|correlation| { + format!( + "the exact 0x000055f3/0x0001/0xff compact-prefix class is now explicit too: dominant name={:?}/{:?} x{}, dominant span={:?} x{}, mode counts={:?}, name-pair counts={:?}, previous short-flag pairs={:?} across {} rows, and sample rows={:?}", + correlation.dominant_primary_name, + correlation.dominant_secondary_name, + correlation.dominant_name_pair_count, + correlation.dominant_profile_span, + correlation.dominant_profile_span_count, + correlation + .mode_family_counts + .iter() + .map(|mode| format!("{}:{}", mode.mode_family, mode.count)) + .collect::>(), + correlation + .name_pair_summaries + .iter() + .map(|entry| format!( + "{:?}/{:?}:{}", + entry.primary_name, entry.secondary_name, entry.count + )) + .collect::>(), + correlation + .previous_short_profile_flag_pair_counts + .iter() + .map(|entry| format!( + "{}/{}:{}", + entry.first_flag_byte_hex, + entry.second_flag_byte_hex, + entry.count + )) + .collect::>(), + correlation.rows_with_previous_short_profile_flag_pair, + correlation + .sample_rows + .iter() + .map(|sample| format!( + "{}:{:?}/{:?}", + sample.name_tag_relative_offset, + sample.primary_name, + sample.secondary_name + )) + .collect::>() + ) + }) + .unwrap_or_else(|| { + "no grounded 0x000055f3/0x0001/0xff compact-prefix correlation was available".to_string() + }), side_buffer .and_then(|probe| probe.payload_envelope_summary.as_ref()) .and_then(|summary| summary.name_prelude_candidate_summary.as_ref()) @@ -13511,26 +13696,53 @@ fn parse_save_placed_structure_dynamic_side_buffer_probe( .collect(), }, ); + let classify_side_buffer_mode_family = + |primary_name: Option<&str>, secondary_name: Option<&str>| -> &'static str { + let name = primary_name.or(secondary_name).unwrap_or_default(); + if name.starts_with("Bridge") { + "bridge" + } else if name.starts_with("Tunnel") { + "tunnel" + } else if name.starts_with("BallastCap") { + "ballast_cap" + } else if name.starts_with("TrackCap") { + "track_cap" + } else if name.starts_with("Overpass") { + "overpass" + } else if name.is_empty() { + "unknown" + } else { + "other" + } + }; let fixed_policy_rows = payload_envelope_rows .iter() .filter(|row| row.policy_chunk_len == Some(0x1a)) .filter_map(|row| { + let embedded_name_row = embedded_name_rows + .iter() + .find(|entry| entry.name_tag_relative_offset == row.name_tag_relative_offset)?; let policy_tag_relative_offset = row.policy_tag_relative_offset?; let policy_payload = records_payload .get(policy_tag_relative_offset + 4..policy_tag_relative_offset + 4 + 0x1a)?; - let first_triplet_dwords = [0usize, 4, 8] - .into_iter() - .map(|offset| read_u32_at(policy_payload, offset)) - .collect::>>()?; - let second_triplet_dwords = [12usize, 16, 20] - .into_iter() - .map(|offset| read_u32_at(policy_payload, offset)) - .collect::>>()?; + let first_triplet_dwords = [ + read_u32_at(policy_payload, 0)?, + read_u32_at(policy_payload, 4)?, + read_u32_at(policy_payload, 8)?, + ]; + let second_triplet_dwords = [ + read_u32_at(policy_payload, 12)?, + read_u32_at(policy_payload, 16)?, + read_u32_at(policy_payload, 20)?, + ]; let trailing_word = read_u16_at(policy_payload, 24)?; Some(( row.name_tag_relative_offset, row.primary_name.clone(), row.secondary_name.clone(), + embedded_name_row.prefix_leading_dword, + embedded_name_row.prefix_trailing_word, + embedded_name_row.prefix_separator_byte, first_triplet_dwords, second_triplet_dwords, trailing_word, @@ -13538,7 +13750,7 @@ fn parse_save_placed_structure_dynamic_side_buffer_probe( }) .collect::>(); let mut fixed_policy_trailing_word_counts = BTreeMap::::new(); - for (_, _, _, _, _, trailing_word) in &fixed_policy_rows { + for (_, _, _, _, _, _, _, _, trailing_word) in &fixed_policy_rows { *fixed_policy_trailing_word_counts .entry(*trailing_word) .or_default() += 1; @@ -13551,6 +13763,219 @@ fn parse_save_placed_structure_dynamic_side_buffer_probe( .then_with(|| right_word.cmp(left_word)) }) .map(|(word, count)| (*word, *count)); + let mut fixed_policy_compact_prefix_groups = BTreeMap::< + (u32, u16, u8), + Vec<( + usize, + Option, + Option, + [u32; 3], + [u32; 3], + u16, + )>, + >::new(); + for ( + name_tag_relative_offset, + primary_name, + secondary_name, + prefix_leading_dword, + prefix_trailing_word, + prefix_separator_byte, + first_triplet_dwords, + second_triplet_dwords, + trailing_word, + ) in &fixed_policy_rows + { + fixed_policy_compact_prefix_groups + .entry(( + *prefix_leading_dword, + *prefix_trailing_word, + *prefix_separator_byte, + )) + .or_default() + .push(( + *name_tag_relative_offset, + primary_name.clone(), + secondary_name.clone(), + *first_triplet_dwords, + *second_triplet_dwords, + *trailing_word, + )); + } + let fixed_policy_compact_prefix_correlations = fixed_policy_compact_prefix_groups + .into_iter() + .map( + |((prefix_leading_dword, prefix_trailing_word, prefix_separator_byte), rows)| { + let mut name_pair_counts = + BTreeMap::<(Option, Option), usize>::new(); + let mut mode_family_counts = BTreeMap::::new(); + let mut policy_tuple_counts = + BTreeMap::<([u32; 3], [u32; 3], u16), usize>::new(); + for ( + _name_tag_relative_offset, + primary_name, + secondary_name, + first_triplet_dwords, + second_triplet_dwords, + trailing_word, + ) in &rows + { + *name_pair_counts + .entry((primary_name.clone(), secondary_name.clone())) + .or_default() += 1; + *mode_family_counts + .entry( + classify_side_buffer_mode_family( + primary_name.as_deref(), + secondary_name.as_deref(), + ) + .to_string(), + ) + .or_default() += 1; + *policy_tuple_counts + .entry(( + *first_triplet_dwords, + *second_triplet_dwords, + *trailing_word, + )) + .or_default() += 1; + } + let dominant_name_pair = name_pair_counts + .iter() + .max_by(|(left_key, left_count), (right_key, right_count)| { + left_count + .cmp(right_count) + .then_with(|| right_key.cmp(left_key)) + }) + .map(|((primary_name, secondary_name), count)| { + (primary_name.clone(), secondary_name.clone(), *count) + }); + let dominant_mode_family = mode_family_counts + .iter() + .max_by(|(left_key, left_count), (right_key, right_count)| { + left_count + .cmp(right_count) + .then_with(|| right_key.cmp(left_key)) + }) + .map(|(mode_family, count)| (mode_family.clone(), *count)); + let dominant_policy_tuple = policy_tuple_counts + .iter() + .max_by(|(left_key, left_count), (right_key, right_count)| { + left_count + .cmp(right_count) + .then_with(|| right_key.cmp(left_key)) + }) + .map( + |( + (first_triplet_dwords, second_triplet_dwords, trailing_word), + count, + )| { + ( + *first_triplet_dwords, + *second_triplet_dwords, + *trailing_word, + *count, + ) + }, + ); + SmpSavePlacedStructureDynamicSideBufferFixedPolicyCompactPrefixCorrelation { + prefix_leading_dword, + prefix_leading_dword_hex: format!("0x{prefix_leading_dword:08x}"), + prefix_trailing_word, + prefix_trailing_word_hex: format!("0x{prefix_trailing_word:04x}"), + prefix_separator_byte, + prefix_separator_byte_hex: format!("0x{prefix_separator_byte:02x}"), + row_count: rows.len(), + unique_policy_tuple_count: policy_tuple_counts.len(), + dominant_primary_name: dominant_name_pair + .as_ref() + .and_then(|(primary_name, _, _)| primary_name.clone()), + dominant_secondary_name: dominant_name_pair + .as_ref() + .and_then(|(_, secondary_name, _)| secondary_name.clone()), + dominant_name_pair_count: dominant_name_pair + .map(|(_, _, count)| count) + .unwrap_or_default(), + dominant_mode_family: dominant_mode_family + .as_ref() + .map(|(mode_family, _)| mode_family.clone()), + dominant_mode_family_count: dominant_mode_family + .map(|(_, count)| count) + .unwrap_or_default(), + dominant_first_triplet_dwords_hex: dominant_policy_tuple + .as_ref() + .map(|(first_triplet_dwords, _, _, _)| { + first_triplet_dwords + .iter() + .map(|value| format!("0x{value:08x}")) + .collect() + }) + .unwrap_or_default(), + dominant_second_triplet_dwords_hex: dominant_policy_tuple + .as_ref() + .map(|(_, second_triplet_dwords, _, _)| { + second_triplet_dwords + .iter() + .map(|value| format!("0x{value:08x}")) + .collect() + }) + .unwrap_or_default(), + dominant_trailing_word: dominant_policy_tuple + .map(|(_, _, trailing_word, _)| trailing_word), + dominant_trailing_word_hex: dominant_policy_tuple + .map(|(_, _, trailing_word, _)| format!("0x{trailing_word:04x}")), + dominant_policy_tuple_count: dominant_policy_tuple + .map(|(_, _, _, count)| count) + .unwrap_or_default(), + mode_family_counts: mode_family_counts + .into_iter() + .map(|(mode_family, count)| { + SmpSavePlacedStructureDynamicSideBufferNamePreludeModeFamilyCount { + mode_family, + count, + } + }) + .collect(), + sample_rows: rows + .iter() + .take(8) + .enumerate() + .map( + |( + sample_index, + ( + name_tag_relative_offset, + primary_name, + secondary_name, + first_triplet_dwords, + second_triplet_dwords, + trailing_word, + ), + )| { + SmpSavePlacedStructureDynamicSideBufferFixedPolicySample { + sample_index, + name_tag_relative_offset: *name_tag_relative_offset, + primary_name: primary_name.clone(), + secondary_name: secondary_name.clone(), + first_triplet_dwords_hex: first_triplet_dwords + .iter() + .map(|value| format!("0x{value:08x}")) + .collect(), + second_triplet_dwords_hex: second_triplet_dwords + .iter() + .map(|value| format!("0x{value:08x}")) + .collect(), + trailing_word: *trailing_word, + trailing_word_hex: format!("0x{trailing_word:04x}"), + } + }, + ) + .collect(), + } + }, + ) + .take(8) + .collect::>(); let fixed_policy_summary = Some(SmpSavePlacedStructureDynamicSideBufferFixedPolicySummary { row_count_with_0x1a_policy_chunk: fixed_policy_rows.len(), @@ -13561,6 +13986,7 @@ fn parse_save_placed_structure_dynamic_side_buffer_probe( dominant_trailing_word_count: dominant_fixed_policy_trailing_word .map(|(_, count)| count) .unwrap_or_default(), + compact_prefix_correlations: fixed_policy_compact_prefix_correlations, sample_rows: fixed_policy_rows .iter() .take(8) @@ -13572,6 +13998,9 @@ fn parse_save_placed_structure_dynamic_side_buffer_probe( name_tag_relative_offset, primary_name, secondary_name, + _prefix_leading_dword, + _prefix_trailing_word, + _prefix_separator_byte, first_triplet_dwords, second_triplet_dwords, trailing_word, @@ -13619,13 +14048,19 @@ fn parse_save_placed_structure_dynamic_side_buffer_probe( .get(previous_index) .and_then(|row| row.profile_chunk_len_to_next_name_or_end) }), + row_index.checked_sub(1).and_then(|previous_index| { + payload_envelope_rows.get(previous_index).and_then(|row| { + row.short_profile_first_flag_byte + .zip(row.short_profile_second_flag_byte) + }) + }), )) }) .collect::>(); let mut name_prelude_candidate_pattern_counts = BTreeMap::<(u16, u8), usize>::new(); let mut name_prelude_child_count_counts = BTreeMap::::new(); let mut name_prelude_saved_primary_counts = BTreeMap::::new(); - for (_, _, _, _, _, _, child_count_candidate, saved_primary_child_byte_candidate, _) in + for (_, _, _, _, _, _, child_count_candidate, saved_primary_child_byte_candidate, _, _) in &name_prelude_candidate_rows { *name_prelude_candidate_pattern_counts @@ -13674,25 +14109,6 @@ fn parse_save_placed_structure_dynamic_side_buffer_probe( .then_with(|| right_key.cmp(left_key)) }) .map(|(value, count)| (*value, *count)); - let classify_side_buffer_mode_family = - |primary_name: Option<&str>, secondary_name: Option<&str>| -> &'static str { - let name = primary_name.or(secondary_name).unwrap_or_default(); - if name.starts_with("Bridge") { - "bridge" - } else if name.starts_with("Tunnel") { - "tunnel" - } else if name.starts_with("BallastCap") { - "ballast_cap" - } else if name.starts_with("TrackCap") { - "track_cap" - } else if name.starts_with("Overpass") { - "overpass" - } else if name.is_empty() { - "unknown" - } else { - "other" - } - }; let mut name_prelude_pattern_groups = BTreeMap::< (u16, u8), Vec<(usize, Option, Option, Option)>, @@ -13707,6 +14123,7 @@ fn parse_save_placed_structure_dynamic_side_buffer_probe( child_count_candidate, saved_primary_child_byte_candidate, previous_span, + _previous_short_profile_flag_pair, ) in &name_prelude_candidate_rows { name_prelude_pattern_groups @@ -13864,6 +14281,7 @@ fn parse_save_placed_structure_dynamic_side_buffer_probe( child_count_candidate, saved_primary_child_byte_candidate, previous_span, + _previous_short_profile_flag_pair, ) in &name_prelude_candidate_rows { if let Some(previous_span) = previous_span { @@ -14081,7 +14499,15 @@ fn parse_save_placed_structure_dynamic_side_buffer_probe( .collect::>(); let mut name_prelude_compact_prefix_groups = BTreeMap::< (u32, u16, u8), - Vec<(usize, Option, Option, u16, u8, Option)>, + Vec<( + usize, + Option, + Option, + u16, + u8, + Option, + Option<(u8, u8)>, + )>, >::new(); for ( name_tag_relative_offset, @@ -14093,6 +14519,7 @@ fn parse_save_placed_structure_dynamic_side_buffer_probe( child_count_candidate, saved_primary_child_byte_candidate, previous_span, + previous_short_profile_flag_pair, ) in &name_prelude_candidate_rows { name_prelude_compact_prefix_groups @@ -14109,6 +14536,7 @@ fn parse_save_placed_structure_dynamic_side_buffer_probe( *child_count_candidate, *saved_primary_child_byte_candidate, *previous_span, + *previous_short_profile_flag_pair, )); } let compact_prefix_correlations = name_prelude_compact_prefix_groups @@ -14123,6 +14551,7 @@ fn parse_save_placed_structure_dynamic_side_buffer_probe( let mut profile_span_counts = BTreeMap::::new(); let mut candidate_pattern_counts = BTreeMap::<(u16, u8), usize>::new(); let mut mode_family_counts = BTreeMap::::new(); + let mut flag_pair_counts = BTreeMap::<(u8, u8), usize>::new(); for ( _name_tag_relative_offset, primary_name, @@ -14130,6 +14559,7 @@ fn parse_save_placed_structure_dynamic_side_buffer_probe( child_count_candidate, saved_primary_child_byte_candidate, previous_span, + previous_short_profile_flag_pair, ) in &rows { *name_pair_counts @@ -14150,6 +14580,13 @@ fn parse_save_placed_structure_dynamic_side_buffer_probe( .to_string(), ) .or_default() += 1; + if let Some((first_flag_byte, second_flag_byte)) = + previous_short_profile_flag_pair + { + *flag_pair_counts + .entry((*first_flag_byte, *second_flag_byte)) + .or_default() += 1; + } } let dominant_name_pair = name_pair_counts .iter() @@ -14264,6 +14701,22 @@ fn parse_save_placed_structure_dynamic_side_buffer_probe( }, ) .collect(), + rows_with_previous_short_profile_flag_pair: flag_pair_counts + .values() + .copied() + .sum(), + previous_short_profile_flag_pair_counts: flag_pair_counts + .into_iter() + .map(|((first_flag_byte, second_flag_byte), count)| { + SmpSavePlacedStructureDynamicSideBufferNamePreludeCompactPrefixFlagPairCount { + first_flag_byte, + first_flag_byte_hex: format!("0x{first_flag_byte:02x}"), + second_flag_byte, + second_flag_byte_hex: format!("0x{second_flag_byte:02x}"), + count, + } + }) + .collect(), sample_rows: rows .iter() .take(8) @@ -14278,6 +14731,7 @@ fn parse_save_placed_structure_dynamic_side_buffer_probe( child_count_candidate, saved_primary_child_byte_candidate, previous_profile_chunk_len_to_next_name_or_end, + _previous_short_profile_flag_pair, ), )| { SmpSavePlacedStructureDynamicSideBufferNamePreludeCompactPrefixSample { @@ -14343,6 +14797,7 @@ fn parse_save_placed_structure_dynamic_side_buffer_probe( child_count_candidate, saved_primary_child_byte_candidate, previous_profile_chunk_len_to_next_name_or_end, + _previous_short_profile_flag_pair, ), )| { SmpSavePlacedStructureDynamicSideBufferNamePreludeCandidateSample { @@ -25115,6 +25570,7 @@ mod tests { dominant_trailing_word: Some(1), dominant_trailing_word_hex: Some("0x0001".to_string()), dominant_trailing_word_count: 118, + compact_prefix_correlations: Vec::new(), sample_rows: Vec::new(), }, ), @@ -25414,6 +25870,16 @@ mod tests { count: 17, }, ], + rows_with_previous_short_profile_flag_pair: 17, + previous_short_profile_flag_pair_counts: vec![ + SmpSavePlacedStructureDynamicSideBufferNamePreludeCompactPrefixFlagPairCount { + first_flag_byte: 0x00, + first_flag_byte_hex: "0x00".to_string(), + second_flag_byte: 0x01, + second_flag_byte_hex: "0x01".to_string(), + count: 17, + }, + ], sample_rows: vec![ SmpSavePlacedStructureDynamicSideBufferNamePreludeCompactPrefixSample { sample_index: 0, @@ -25473,6 +25939,16 @@ mod tests { count: 1, }, ], + rows_with_previous_short_profile_flag_pair: 1, + previous_short_profile_flag_pair_counts: vec![ + SmpSavePlacedStructureDynamicSideBufferNamePreludeCompactPrefixFlagPairCount { + first_flag_byte: 0x00, + first_flag_byte_hex: "0x00".to_string(), + second_flag_byte: 0x01, + second_flag_byte_hex: "0x01".to_string(), + count: 1, + }, + ], sample_rows: vec![ SmpSavePlacedStructureDynamicSideBufferNamePreludeCompactPrefixSample { sample_index: 0, @@ -25532,6 +26008,16 @@ mod tests { count: 2, }, ], + rows_with_previous_short_profile_flag_pair: 2, + previous_short_profile_flag_pair_counts: vec![ + SmpSavePlacedStructureDynamicSideBufferNamePreludeCompactPrefixFlagPairCount { + first_flag_byte: 0x00, + first_flag_byte_hex: "0x00".to_string(), + second_flag_byte: 0x01, + second_flag_byte_hex: "0x01".to_string(), + count: 2, + }, + ], sample_rows: vec![ SmpSavePlacedStructureDynamicSideBufferNamePreludeCompactPrefixSample { sample_index: 0, @@ -25708,11 +26194,13 @@ mod tests { trace.candidate_consumer_hypotheses[0] .blockers .iter() - .any(|line| line.contains("remaining mixed exact compact-prefix classes") - && line.contains("0xff0000ff/0x0002/0xff is pure bridge") - && line.contains("0x0005d368/0x0001/0xff is pure track-cap") - && line.contains("0xff0000ff/0x0001/0xff") - && line.contains("0x000055f3/0x0001/0xff")) + .any( + |line| line.contains("remaining mixed exact compact-prefix classes") + && line.contains("0xff0000ff/0x0002/0xff is pure bridge") + && line.contains("0x0005d368/0x0001/0xff is pure track-cap") + && line.contains("0xff0000ff/0x0001/0xff") + && line.contains("0x000055f3/0x0001/0xff") + ) ); assert!( trace.candidate_consumer_hypotheses[0] @@ -25880,18 +26368,22 @@ mod tests { trace.candidate_consumer_hypotheses[0] .evidence .iter() - .any(|line| line.contains("objdump on 0x531030/0x5a464d/0x5a44a8") - && line.contains("0x531030 just forwards") - && line.contains("0x5a44a8 is the shared chunked stream write path")) + .any( + |line| line.contains("objdump on 0x531030/0x5a464d/0x5a44a8") + && line.contains("0x531030 just forwards") + && line.contains("0x5a44a8 is the shared chunked stream write path") + ) ); assert!( trace.candidate_consumer_hypotheses[0] .evidence .iter() - .any(|line| line.contains("cannot come from selector-copy state alone") - && line.contains("0xff0000ff/0x0001/0xff") - && line.contains("dominant TrackCap rows") - && line.contains("tunnel residue")) + .any( + |line| line.contains("cannot come from selector-copy state alone") + && line.contains("0xff0000ff/0x0001/0xff") + && line.contains("dominant TrackCap rows") + && line.contains("tunnel residue") + ) ); assert!( trace.candidate_consumer_hypotheses[0]