Summarize peer-site payload ladders
This commit is contained in:
parent
aa4147fcf2
commit
26848f96e6
2 changed files with 228 additions and 0 deletions
|
|
@ -3555,6 +3555,23 @@ pub struct SmpPeriodicCompanyServiceTraceEntry {
|
|||
pub branches: Vec<SmpServiceTraceBranchStatus>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct SmpSavePlacedStructureProfilePayloadSummaryEntry {
|
||||
pub profile_payload_dword_hex: String,
|
||||
pub profile_status_kind: String,
|
||||
pub count: usize,
|
||||
#[serde(default)]
|
||||
pub sample_primary_names: Vec<String>,
|
||||
#[serde(default)]
|
||||
pub sample_secondary_names: Vec<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct SmpSavePlacedStructureProfilePayloadDeltaSummaryEntry {
|
||||
pub delta_hex: String,
|
||||
pub count: usize,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct SmpPeriodicCompanyServiceTraceReport {
|
||||
pub profile_family: String,
|
||||
|
|
@ -3577,6 +3594,12 @@ pub struct SmpPeriodicCompanyServiceTraceReport {
|
|||
#[serde(default)]
|
||||
pub peer_site_selector_candidate_helper_linkage: Vec<String>,
|
||||
#[serde(default)]
|
||||
pub peer_site_selector_candidate_saved_payload_summaries:
|
||||
Vec<SmpSavePlacedStructureProfilePayloadSummaryEntry>,
|
||||
#[serde(default)]
|
||||
pub peer_site_selector_candidate_saved_payload_delta_summaries:
|
||||
Vec<SmpSavePlacedStructureProfilePayloadDeltaSummaryEntry>,
|
||||
#[serde(default)]
|
||||
pub peer_site_restore_input_fields: Vec<String>,
|
||||
#[serde(default)]
|
||||
pub peer_site_runtime_input_fields: Vec<String>,
|
||||
|
|
@ -4174,6 +4197,97 @@ pub fn inspect_save_periodic_company_service_trace_file(
|
|||
Ok(trace)
|
||||
}
|
||||
|
||||
fn summarize_peer_site_selector_candidate_saved_payloads(
|
||||
analysis: &SmpSaveCompanyChairmanAnalysisReport,
|
||||
) -> Vec<SmpSavePlacedStructureProfilePayloadSummaryEntry> {
|
||||
let Some(triplets) = analysis.placed_structure_record_triplets.as_ref() else {
|
||||
return Vec::new();
|
||||
};
|
||||
let mut grouped =
|
||||
BTreeMap::<(String, String), (usize, BTreeSet<String>, BTreeSet<String>)>::new();
|
||||
for entry in &triplets.entries {
|
||||
let grouped_entry = grouped
|
||||
.entry((
|
||||
entry.profile_payload_dword_hex.clone(),
|
||||
entry.profile_status_kind.clone(),
|
||||
))
|
||||
.or_insert_with(|| (0, BTreeSet::new(), BTreeSet::new()));
|
||||
grouped_entry.0 += 1;
|
||||
if grouped_entry.1.len() < 4 {
|
||||
grouped_entry.1.insert(entry.primary_name.clone());
|
||||
}
|
||||
if grouped_entry.2.len() < 4 {
|
||||
grouped_entry.2.insert(entry.secondary_name.clone());
|
||||
}
|
||||
}
|
||||
let mut summaries = grouped
|
||||
.into_iter()
|
||||
.map(
|
||||
|(
|
||||
(profile_payload_dword_hex, profile_status_kind),
|
||||
(count, primary_names, secondary_names),
|
||||
)| {
|
||||
SmpSavePlacedStructureProfilePayloadSummaryEntry {
|
||||
profile_payload_dword_hex,
|
||||
profile_status_kind,
|
||||
count,
|
||||
sample_primary_names: primary_names.into_iter().collect(),
|
||||
sample_secondary_names: secondary_names.into_iter().collect(),
|
||||
}
|
||||
},
|
||||
)
|
||||
.collect::<Vec<_>>();
|
||||
summaries.sort_by(|left, right| {
|
||||
right
|
||||
.count
|
||||
.cmp(&left.count)
|
||||
.then_with(|| {
|
||||
left.profile_payload_dword_hex
|
||||
.cmp(&right.profile_payload_dword_hex)
|
||||
})
|
||||
.then_with(|| left.profile_status_kind.cmp(&right.profile_status_kind))
|
||||
});
|
||||
summaries.truncate(8);
|
||||
summaries
|
||||
}
|
||||
|
||||
fn summarize_peer_site_selector_candidate_saved_payload_deltas(
|
||||
analysis: &SmpSaveCompanyChairmanAnalysisReport,
|
||||
) -> Vec<SmpSavePlacedStructureProfilePayloadDeltaSummaryEntry> {
|
||||
let Some(triplets) = analysis.placed_structure_record_triplets.as_ref() else {
|
||||
return Vec::new();
|
||||
};
|
||||
let mut payload_values = triplets
|
||||
.entries
|
||||
.iter()
|
||||
.map(|entry| entry.profile_payload_dword)
|
||||
.collect::<Vec<_>>();
|
||||
payload_values.sort_unstable();
|
||||
payload_values.dedup();
|
||||
let mut delta_counts = BTreeMap::<u32, usize>::new();
|
||||
for window in payload_values.windows(2) {
|
||||
let delta = window[1].wrapping_sub(window[0]);
|
||||
*delta_counts.entry(delta).or_insert(0) += 1;
|
||||
}
|
||||
let mut summaries = delta_counts
|
||||
.into_iter()
|
||||
.map(
|
||||
|(delta, count)| SmpSavePlacedStructureProfilePayloadDeltaSummaryEntry {
|
||||
delta_hex: format!("0x{delta:08x}"),
|
||||
count,
|
||||
},
|
||||
)
|
||||
.collect::<Vec<_>>();
|
||||
summaries.sort_by(|left, right| {
|
||||
right
|
||||
.count
|
||||
.cmp(&left.count)
|
||||
.then_with(|| left.delta_hex.cmp(&right.delta_hex))
|
||||
});
|
||||
summaries.truncate(6);
|
||||
summaries
|
||||
}
|
||||
|
||||
fn build_periodic_company_service_trace_report(
|
||||
analysis: &SmpSaveCompanyChairmanAnalysisReport,
|
||||
) -> SmpPeriodicCompanyServiceTraceReport {
|
||||
|
|
@ -4198,6 +4312,10 @@ fn build_periodic_company_service_trace_report(
|
|||
"0x0040d1e1 -> 0x0045c3c0 consumes the same owner family's [site+0x246] child lane"
|
||||
.to_string(),
|
||||
];
|
||||
let peer_site_selector_candidate_saved_payload_summaries =
|
||||
summarize_peer_site_selector_candidate_saved_payloads(analysis);
|
||||
let peer_site_selector_candidate_saved_payload_delta_summaries =
|
||||
summarize_peer_site_selector_candidate_saved_payload_deltas(analysis);
|
||||
let peer_site_restore_input_fields = vec![
|
||||
"[site+0x3cc] saved placed-structure id feeding 0x62b2fc".to_string(),
|
||||
"[site+0x3d0] saved companion-region id from [placed+0x173] feeding 0x62b268".to_string(),
|
||||
|
|
@ -4504,6 +4622,17 @@ fn build_periodic_company_service_trace_report(
|
|||
notes.push(
|
||||
"Direct disassembly now closes the negative persistence side too: the direct 0x36b1 per-record callbacks serialize the shared base scalar triplets rooted at [this+0x206/+0x20a/+0x20e] plus the subordinate payload callback strip, while the 0x4a9d/0x4a3a/0x4a3b side-buffer owner only persists route-entry lists, three byte arrays, five proximity buckets, and the sampled-cell list. That means neither checked-in save owner seam currently persists the core peer-site identity fields [site+0x04], [site+0x2a8], or [peer+0x08] directly.".to_string(),
|
||||
);
|
||||
if !peer_site_selector_candidate_saved_payload_summaries.is_empty() {
|
||||
notes.push(format!(
|
||||
"The periodic-company trace now also carries a compact save-side summary of the tagged 0x5dc1 placed-structure profile payload/status pairs already parsed from the 0x36b1 triplet seam; dominant current pair is {} / {} x{}, and dominant adjacent payload delta is {:?}.",
|
||||
peer_site_selector_candidate_saved_payload_summaries[0].profile_payload_dword_hex,
|
||||
peer_site_selector_candidate_saved_payload_summaries[0].profile_status_kind,
|
||||
peer_site_selector_candidate_saved_payload_summaries[0].count,
|
||||
peer_site_selector_candidate_saved_payload_delta_summaries
|
||||
.first()
|
||||
.map(|entry| entry.delta_hex.as_str())
|
||||
));
|
||||
}
|
||||
notes.push(
|
||||
"The replay strip is tighter now too. 0x00444690 is the current late world bring-up caller of 0x004133b0, that outer owner drains queued site ids through 0x0040e450 and then sweeps every live placed structure through 0x0040ee10, and 0x0040ee10 itself reaches 0x0040edf6 -> 0x00480710 plus the later 0x0040e360 follow-on. A separate runtime path at 0x004160aa also re-enters 0x0040ee10 later. So [peer+0x08] replay is no longer the open question, and [site+0x04] is no longer an owner mystery either: the local linked-site helper strip seeds [site+0x3cc/+0x3d0] from 0x62b2fc / 0x62b268, reaches the save-backed 0x0045c150 / 0x0045c310 owner directly, that owner fills [owner+0x23e/+0x242] from tagged payload 0x5dc1, and 0x0045c36e then feeds [owner+0x23e] through 0x00456100 -> 0x00455b70 -> 0x0052edf0 into [site+0x04]. The remaining non-hook target is now the smaller shellless-simulation question: which subset of those persisted site/peer fields is actually sufficient to run 0x004014b0 and its city-connection sibling without shell state.".to_string(),
|
||||
);
|
||||
|
|
@ -4521,6 +4650,8 @@ fn build_periodic_company_service_trace_report(
|
|||
peer_site_selector_candidate_selector_lane,
|
||||
peer_site_selector_candidate_class_identity_status,
|
||||
peer_site_selector_candidate_helper_linkage,
|
||||
peer_site_selector_candidate_saved_payload_summaries,
|
||||
peer_site_selector_candidate_saved_payload_delta_summaries,
|
||||
peer_site_restore_input_fields,
|
||||
peer_site_runtime_input_fields,
|
||||
peer_site_runtime_reconstruction_status,
|
||||
|
|
@ -27094,6 +27225,76 @@ mod tests {
|
|||
fn builds_periodic_company_service_trace_report_with_candidate_consumers() {
|
||||
let mut analysis = empty_analysis_report();
|
||||
analysis.selected_company_id = Some(7);
|
||||
analysis.placed_structure_record_triplets =
|
||||
Some(SmpSavePlacedStructureRecordTripletProbe {
|
||||
profile_family: analysis.profile_family.clone(),
|
||||
source_kind: "save-placed-structure-record-triplets".to_string(),
|
||||
semantic_family: "scenario-save-placed-structure-record-triplets".to_string(),
|
||||
records_tag_offset: 0,
|
||||
close_tag_offset: 0,
|
||||
record_count: 2,
|
||||
entries: vec![
|
||||
SmpSavePlacedStructureRecordTripletEntryProbe {
|
||||
record_index: 0,
|
||||
primary_name: "StationA".to_string(),
|
||||
secondary_name: "StationSetA".to_string(),
|
||||
name_tag_relative_offset: 0,
|
||||
policy_tag_relative_offset: 0,
|
||||
profile_tag_relative_offset: 0,
|
||||
policy_chunk_len: 0x1a,
|
||||
profile_chunk_len: 0x20,
|
||||
policy_f32_lane_0: 0.0,
|
||||
policy_f32_lane_1: 0.0,
|
||||
policy_f32_lane_2: 0.0,
|
||||
policy_f32_lane_3: 0.0,
|
||||
policy_f32_lane_4: 0.0,
|
||||
policy_reserved_dword: 0,
|
||||
policy_trailing_word: 0x0101,
|
||||
policy_trailing_word_hex: "0x0101".to_string(),
|
||||
profile_open_marker: 0x5dc1,
|
||||
profile_open_marker_hex: "0x00005dc1".to_string(),
|
||||
profile_repeated_primary_name: "StationA".to_string(),
|
||||
profile_repeated_secondary_name: "StationSetA".to_string(),
|
||||
profile_payload_dword: 0x0e373880,
|
||||
profile_payload_dword_hex: "0x0e373880".to_string(),
|
||||
profile_sentinel_i32: -1,
|
||||
profile_status_kind: "unset".to_string(),
|
||||
farm_growth_stage_index: None,
|
||||
profile_close_marker: 0x5dc2,
|
||||
profile_close_marker_hex: "0x00005dc2".to_string(),
|
||||
},
|
||||
SmpSavePlacedStructureRecordTripletEntryProbe {
|
||||
record_index: 1,
|
||||
primary_name: "StationB".to_string(),
|
||||
secondary_name: "StationSetB".to_string(),
|
||||
name_tag_relative_offset: 0,
|
||||
policy_tag_relative_offset: 0,
|
||||
profile_tag_relative_offset: 0,
|
||||
policy_chunk_len: 0x1a,
|
||||
profile_chunk_len: 0x20,
|
||||
policy_f32_lane_0: 0.0,
|
||||
policy_f32_lane_1: 0.0,
|
||||
policy_f32_lane_2: 0.0,
|
||||
policy_f32_lane_3: 0.0,
|
||||
policy_f32_lane_4: 0.0,
|
||||
policy_reserved_dword: 0,
|
||||
policy_trailing_word: 0x0101,
|
||||
policy_trailing_word_hex: "0x0101".to_string(),
|
||||
profile_open_marker: 0x5dc1,
|
||||
profile_open_marker_hex: "0x00005dc1".to_string(),
|
||||
profile_repeated_primary_name: "StationB".to_string(),
|
||||
profile_repeated_secondary_name: "StationSetB".to_string(),
|
||||
profile_payload_dword: 0x0e373500,
|
||||
profile_payload_dword_hex: "0x0e373500".to_string(),
|
||||
profile_sentinel_i32: -1,
|
||||
profile_status_kind: "unset".to_string(),
|
||||
farm_growth_stage_index: None,
|
||||
profile_close_marker: 0x5dc2,
|
||||
profile_close_marker_hex: "0x00005dc2".to_string(),
|
||||
},
|
||||
],
|
||||
evidence: Vec::new(),
|
||||
});
|
||||
analysis
|
||||
.company_entries
|
||||
.push(SmpSaveCompanyRecordAnalysisEntry {
|
||||
|
|
@ -27154,6 +27355,24 @@ mod tests {
|
|||
"grounded_direct_local_helper_strip"
|
||||
);
|
||||
assert_eq!(trace.peer_site_selector_candidate_helper_linkage.len(), 4);
|
||||
assert_eq!(
|
||||
trace
|
||||
.peer_site_selector_candidate_saved_payload_summaries
|
||||
.len(),
|
||||
2
|
||||
);
|
||||
assert_eq!(
|
||||
trace.peer_site_selector_candidate_saved_payload_summaries[0].profile_payload_dword_hex,
|
||||
"0x0e373500"
|
||||
);
|
||||
assert_eq!(
|
||||
trace.peer_site_selector_candidate_saved_payload_summaries[0].count,
|
||||
1
|
||||
);
|
||||
assert_eq!(
|
||||
trace.peer_site_selector_candidate_saved_payload_delta_summaries[0].delta_hex,
|
||||
"0x00000380"
|
||||
);
|
||||
assert_eq!(trace.peer_site_restore_input_fields.len(), 4);
|
||||
assert_eq!(trace.peer_site_runtime_input_fields.len(), 3);
|
||||
assert_eq!(
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue