Classify machine shop Tier-2 selector outlier
This commit is contained in:
parent
2158d1e39e
commit
7894c52aea
5 changed files with 6714 additions and 278 deletions
File diff suppressed because it is too large
Load diff
|
|
@ -96,6 +96,7 @@ pub struct BuildingTypeRecoveredTableSummary {
|
||||||
pub nonzero_bty_header_name_0x40_summaries: Vec<BuildingTypeBtyHeaderNameSummary>,
|
pub nonzero_bty_header_name_0x40_summaries: Vec<BuildingTypeBtyHeaderNameSummary>,
|
||||||
pub nonzero_bty_header_name_0x5e_summaries: Vec<BuildingTypeBtyHeaderNameSummary>,
|
pub nonzero_bty_header_name_0x5e_summaries: Vec<BuildingTypeBtyHeaderNameSummary>,
|
||||||
pub nonzero_bty_header_name_0x7c_summaries: Vec<BuildingTypeBtyHeaderNameSummary>,
|
pub nonzero_bty_header_name_0x7c_summaries: Vec<BuildingTypeBtyHeaderNameSummary>,
|
||||||
|
pub nonzero_bty_header_alias_selector_summaries: Vec<BuildingTypeBtyHeaderAliasSelectorSummary>,
|
||||||
pub bty_header_name_0x5e_dword_summaries: Vec<BuildingTypeBtyHeaderNameDwordSummary>,
|
pub bty_header_name_0x5e_dword_summaries: Vec<BuildingTypeBtyHeaderNameDwordSummary>,
|
||||||
pub bty_name_0x5e_bca_selector_summaries: Vec<BuildingTypeBtyNameBcaSelectorSummary>,
|
pub bty_name_0x5e_bca_selector_summaries: Vec<BuildingTypeBtyNameBcaSelectorSummary>,
|
||||||
}
|
}
|
||||||
|
|
@ -126,6 +127,21 @@ pub struct BuildingTypeBtyHeaderNameDwordSummary {
|
||||||
pub sample_file_names: Vec<String>,
|
pub sample_file_names: Vec<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
|
pub struct BuildingTypeBtyHeaderAliasSelectorSummary {
|
||||||
|
pub name_0x40: String,
|
||||||
|
pub name_0x5e: String,
|
||||||
|
pub name_0x7c: String,
|
||||||
|
pub dword_0xbb: u32,
|
||||||
|
pub dword_0xbb_hex: String,
|
||||||
|
pub byte_0xb8_hex: String,
|
||||||
|
pub byte_0xb9_hex: String,
|
||||||
|
pub byte_0xba_hex: String,
|
||||||
|
pub byte_0xbb_hex: String,
|
||||||
|
pub file_count: usize,
|
||||||
|
pub sample_file_names: Vec<String>,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
pub struct BuildingTypeBtyNameBcaSelectorSummary {
|
pub struct BuildingTypeBtyNameBcaSelectorSummary {
|
||||||
pub header_offset_hex: String,
|
pub header_offset_hex: String,
|
||||||
|
|
@ -507,6 +523,8 @@ fn summarize_recovered_table_families(
|
||||||
summarize_nonzero_bty_header_name_lane(files, 0x5e, |probe| &probe.name_0x5e);
|
summarize_nonzero_bty_header_name_lane(files, 0x5e, |probe| &probe.name_0x5e);
|
||||||
let nonzero_bty_header_name_0x7c_summaries =
|
let nonzero_bty_header_name_0x7c_summaries =
|
||||||
summarize_nonzero_bty_header_name_lane(files, 0x7c, |probe| &probe.name_0x7c);
|
summarize_nonzero_bty_header_name_lane(files, 0x7c, |probe| &probe.name_0x7c);
|
||||||
|
let nonzero_bty_header_alias_selector_summaries =
|
||||||
|
summarize_nonzero_bty_header_alias_selector_patterns(entries, files);
|
||||||
let bty_header_name_0x5e_dword_summaries =
|
let bty_header_name_0x5e_dword_summaries =
|
||||||
summarize_bty_header_name_lane_by_dword(files, 0x5e, |probe| &probe.name_0x5e);
|
summarize_bty_header_name_lane_by_dword(files, 0x5e, |probe| &probe.name_0x5e);
|
||||||
let bty_name_0x5e_bca_selector_summaries =
|
let bty_name_0x5e_bca_selector_summaries =
|
||||||
|
|
@ -528,6 +546,7 @@ fn summarize_recovered_table_families(
|
||||||
nonzero_bty_header_name_0x40_summaries,
|
nonzero_bty_header_name_0x40_summaries,
|
||||||
nonzero_bty_header_name_0x5e_summaries,
|
nonzero_bty_header_name_0x5e_summaries,
|
||||||
nonzero_bty_header_name_0x7c_summaries,
|
nonzero_bty_header_name_0x7c_summaries,
|
||||||
|
nonzero_bty_header_alias_selector_summaries,
|
||||||
bty_header_name_0x5e_dword_summaries,
|
bty_header_name_0x5e_dword_summaries,
|
||||||
bty_name_0x5e_bca_selector_summaries,
|
bty_name_0x5e_bca_selector_summaries,
|
||||||
}
|
}
|
||||||
|
|
@ -700,6 +719,112 @@ fn summarize_bty_name_0x5e_bca_selector_patterns(
|
||||||
summaries
|
summaries
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn summarize_nonzero_bty_header_alias_selector_patterns(
|
||||||
|
entries: &[BuildingTypeSourceEntry],
|
||||||
|
files: &[BuildingTypeSourceFile],
|
||||||
|
) -> Vec<BuildingTypeBtyHeaderAliasSelectorSummary> {
|
||||||
|
let file_by_name = files
|
||||||
|
.iter()
|
||||||
|
.map(|file| (file.file_name.as_str(), file))
|
||||||
|
.collect::<BTreeMap<_, _>>();
|
||||||
|
let mut groups = BTreeMap::<
|
||||||
|
(String, String, String, u32, String, String, String, String),
|
||||||
|
Vec<String>,
|
||||||
|
>::new();
|
||||||
|
|
||||||
|
for entry in entries {
|
||||||
|
let bty_file = entry
|
||||||
|
.file_names
|
||||||
|
.iter()
|
||||||
|
.filter_map(|name| file_by_name.get(name.as_str()))
|
||||||
|
.find(|file| matches!(file.source_kind, BuildingTypeSourceKind::Bty));
|
||||||
|
let bca_file = entry
|
||||||
|
.file_names
|
||||||
|
.iter()
|
||||||
|
.filter_map(|name| file_by_name.get(name.as_str()))
|
||||||
|
.find(|file| matches!(file.source_kind, BuildingTypeSourceKind::Bca));
|
||||||
|
let (Some(bty_file), Some(bca_file)) = (bty_file, bca_file) else {
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
let (Some(bty_probe), Some(bca_probe)) =
|
||||||
|
(&bty_file.bty_header_probe, &bca_file.bca_selector_probe)
|
||||||
|
else {
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
if bty_probe.dword_0xbb == 0 {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
let name_0x40 = bty_probe.name_0x40.trim();
|
||||||
|
let name_0x5e = bty_probe.name_0x5e.trim();
|
||||||
|
let name_0x7c = bty_probe.name_0x7c.trim();
|
||||||
|
if name_0x40.is_empty() || name_0x5e.is_empty() || name_0x7c.is_empty() {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
groups
|
||||||
|
.entry((
|
||||||
|
name_0x40.to_string(),
|
||||||
|
name_0x5e.to_string(),
|
||||||
|
name_0x7c.to_string(),
|
||||||
|
bty_probe.dword_0xbb,
|
||||||
|
bca_probe.byte_0xb8_hex.clone(),
|
||||||
|
bca_probe.byte_0xb9_hex.clone(),
|
||||||
|
bca_probe.byte_0xba_hex.clone(),
|
||||||
|
bca_probe.byte_0xbb_hex.clone(),
|
||||||
|
))
|
||||||
|
.or_default()
|
||||||
|
.push(bty_file.file_name.clone());
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut summaries = groups
|
||||||
|
.into_iter()
|
||||||
|
.map(
|
||||||
|
|(
|
||||||
|
(
|
||||||
|
name_0x40,
|
||||||
|
name_0x5e,
|
||||||
|
name_0x7c,
|
||||||
|
dword_0xbb,
|
||||||
|
byte_0xb8_hex,
|
||||||
|
byte_0xb9_hex,
|
||||||
|
byte_0xba_hex,
|
||||||
|
byte_0xbb_hex,
|
||||||
|
),
|
||||||
|
mut file_names,
|
||||||
|
)| {
|
||||||
|
file_names.sort();
|
||||||
|
file_names.dedup();
|
||||||
|
BuildingTypeBtyHeaderAliasSelectorSummary {
|
||||||
|
name_0x40,
|
||||||
|
name_0x5e,
|
||||||
|
name_0x7c,
|
||||||
|
dword_0xbb,
|
||||||
|
dword_0xbb_hex: format!("0x{dword_0xbb:08x}"),
|
||||||
|
byte_0xb8_hex,
|
||||||
|
byte_0xb9_hex,
|
||||||
|
byte_0xba_hex,
|
||||||
|
byte_0xbb_hex,
|
||||||
|
file_count: file_names.len(),
|
||||||
|
sample_file_names: file_names.into_iter().take(24).collect(),
|
||||||
|
}
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
summaries.sort_by(|left, right| {
|
||||||
|
right
|
||||||
|
.file_count
|
||||||
|
.cmp(&left.file_count)
|
||||||
|
.then_with(|| left.dword_0xbb.cmp(&right.dword_0xbb))
|
||||||
|
.then_with(|| left.name_0x40.cmp(&right.name_0x40))
|
||||||
|
.then_with(|| left.name_0x5e.cmp(&right.name_0x5e))
|
||||||
|
.then_with(|| left.name_0x7c.cmp(&right.name_0x7c))
|
||||||
|
.then_with(|| left.byte_0xb8_hex.cmp(&right.byte_0xb8_hex))
|
||||||
|
.then_with(|| left.byte_0xb9_hex.cmp(&right.byte_0xb9_hex))
|
||||||
|
.then_with(|| left.byte_0xba_hex.cmp(&right.byte_0xba_hex))
|
||||||
|
.then_with(|| left.byte_0xbb_hex.cmp(&right.byte_0xbb_hex))
|
||||||
|
});
|
||||||
|
summaries
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, Deserialize)]
|
#[derive(Debug, Clone, PartialEq, Eq, Deserialize)]
|
||||||
struct BuildingBindingArtifact {
|
struct BuildingBindingArtifact {
|
||||||
bindings: Vec<BuildingBindingRow>,
|
bindings: Vec<BuildingBindingRow>,
|
||||||
|
|
@ -908,6 +1033,22 @@ mod tests {
|
||||||
sample_file_names: vec!["Port.bty".to_string()],
|
sample_file_names: vec!["Port.bty".to_string()],
|
||||||
}]
|
}]
|
||||||
);
|
);
|
||||||
|
assert_eq!(
|
||||||
|
summary.nonzero_bty_header_alias_selector_summaries,
|
||||||
|
vec![BuildingTypeBtyHeaderAliasSelectorSummary {
|
||||||
|
name_0x40: "Port".to_string(),
|
||||||
|
name_0x5e: "TextileMill".to_string(),
|
||||||
|
name_0x7c: "Port".to_string(),
|
||||||
|
dword_0xbb: 0x01f4,
|
||||||
|
dword_0xbb_hex: "0x000001f4".to_string(),
|
||||||
|
byte_0xb8_hex: "0x00".to_string(),
|
||||||
|
byte_0xb9_hex: "0x00".to_string(),
|
||||||
|
byte_0xba_hex: "0x00".to_string(),
|
||||||
|
byte_0xbb_hex: "0x00".to_string(),
|
||||||
|
file_count: 1,
|
||||||
|
sample_file_names: vec!["Port.bty".to_string()],
|
||||||
|
}]
|
||||||
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
summary.bty_name_0x5e_bca_selector_summaries,
|
summary.bty_name_0x5e_bca_selector_summaries,
|
||||||
vec![BuildingTypeBtyNameBcaSelectorSummary {
|
vec![BuildingTypeBtyNameBcaSelectorSummary {
|
||||||
|
|
|
||||||
|
|
@ -108,6 +108,14 @@
|
||||||
`MachineShop` inside the `TextileMill` cluster (`byte_0xba = 0x3f`, `byte_0xbb = 0x00`). So the
|
`MachineShop` inside the `TextileMill` cluster (`byte_0xba = 0x3f`, `byte_0xbb = 0x00`). So the
|
||||||
next load-side source-selection pass should focus on that row-level outlier and any matching
|
next load-side source-selection pass should focus on that row-level outlier and any matching
|
||||||
replay/seed logic, not on a whole-cluster nonzero bank hypothesis.
|
replay/seed logic, not on a whole-cluster nonzero bank hypothesis.
|
||||||
|
The direct-name plus alias plus selector join sharpens that one more step: inside the same
|
||||||
|
nonzero `0x000001f4` family, the direct `Warehouse/TextileMill/Warehouse` shape splits into six
|
||||||
|
all-zero selector peers (`ConcretePlant`, `ConstructionFirm`, `ElectronicsPlant`, `Hospital`,
|
||||||
|
`PharmaceuticalPlant`, and `Warehouse`) plus one unique selector outlier,
|
||||||
|
`MachineShop = 0x00/0x80/0x3f/0x00`. The sibling bare `Port/TextileMill/Port` row stays
|
||||||
|
all-zero. So the remaining load-side question is no longer whether the bare `Port` / `Warehouse`
|
||||||
|
row carries the stock exception; it is why one warehouse-shaped industrial peer in that same
|
||||||
|
alias family carries the lone selector while the bare rows do not.
|
||||||
The global stock selector report tightens that further: the full `MachineShop.bca` signature
|
The global stock selector report tightens that further: the full `MachineShop.bca` signature
|
||||||
(`0x00/0x80/0x3f/0x00` across `0xb8..0xbb`) is unique across the checked-in stock `.bca`
|
(`0x00/0x80/0x3f/0x00` across `0xb8..0xbb`) is unique across the checked-in stock `.bca`
|
||||||
corpus. So the remaining load-side Tier-2 frontier is one surfaced stock-file outlier plus the
|
corpus. So the remaining load-side Tier-2 frontier is one surfaced stock-file outlier plus the
|
||||||
|
|
|
||||||
|
|
@ -1356,6 +1356,14 @@
|
||||||
longer ask whether whole alias clusters map to nonzero bank bytes; it should ask why one
|
longer ask whether whole alias clusters map to nonzero bank bytes; it should ask why one
|
||||||
specific stock row inside the `TextileMill` cluster surfaces a nonzero selector while its peer
|
specific stock row inside the `TextileMill` cluster surfaces a nonzero selector while its peer
|
||||||
rows stay zero.
|
rows stay zero.
|
||||||
|
The direct-name plus alias plus selector join narrows that one step further. Inside the same
|
||||||
|
nonzero `0x000001f4` family, the direct `Warehouse/TextileMill/Warehouse` shape splits into six
|
||||||
|
all-zero selector peers (`ConcretePlant`, `ConstructionFirm`, `ElectronicsPlant`, `Hospital`,
|
||||||
|
`PharmaceuticalPlant`, and `Warehouse`) plus one unique selector outlier,
|
||||||
|
`MachineShop = 0x00/0x80/0x3f/0x00`. The sibling bare `Port/TextileMill/Port` row stays
|
||||||
|
all-zero. So the remaining Tier-2 source question is no longer whether the bare `Port` or
|
||||||
|
`Warehouse` row carries the seeded selector; it is why one warehouse-shaped industrial peer in
|
||||||
|
that alias family carries the lone seeded selector while the bare rows do not.
|
||||||
The global stock `.bca` selector report narrows that again: the exact `MachineShop.bca`
|
The global stock `.bca` selector report narrows that again: the exact `MachineShop.bca`
|
||||||
signature (`byte_0xb8 = 0x00`, `byte_0xb9 = 0x80`, `byte_0xba = 0x3f`, `byte_0xbb = 0x00`) is
|
signature (`byte_0xb8 = 0x00`, `byte_0xb9 = 0x80`, `byte_0xba = 0x3f`, `byte_0xbb = 0x00`) is
|
||||||
unique across the checked-in stock corpus. So the remaining Tier-2 source frontier is not a
|
unique across the checked-in stock corpus. So the remaining Tier-2 source frontier is not a
|
||||||
|
|
|
||||||
|
|
@ -1314,6 +1314,15 @@ Working rule:
|
||||||
So the next Tier-2 source-selection pass should no longer ask whether whole alias clusters map
|
So the next Tier-2 source-selection pass should no longer ask whether whole alias clusters map
|
||||||
to nonzero bank bytes; it should ask why one specific stock row inside the `TextileMill`
|
to nonzero bank bytes; it should ask why one specific stock row inside the `TextileMill`
|
||||||
cluster surfaces a nonzero selector while its peer rows stay zero
|
cluster surfaces a nonzero selector while its peer rows stay zero
|
||||||
|
- the direct-name plus alias plus selector join narrows that one step further:
|
||||||
|
inside the same nonzero `0x000001f4` family, the direct
|
||||||
|
`Warehouse/TextileMill/Warehouse` shape splits into six all-zero selector peers
|
||||||
|
(`ConcretePlant`, `ConstructionFirm`, `ElectronicsPlant`, `Hospital`,
|
||||||
|
`PharmaceuticalPlant`, and `Warehouse`) plus one unique selector outlier,
|
||||||
|
`MachineShop = 0x00/0x80/0x3f/0x00`. The sibling bare `Port/TextileMill/Port` row stays
|
||||||
|
all-zero. So the remaining Tier-2 question is no longer “does the bare `Port` or
|
||||||
|
`Warehouse` row carry the seeded selector?”; it is “why does one warehouse-shaped industrial
|
||||||
|
peer in that alias family carry the lone seeded selector while the bare rows do not?”
|
||||||
- the global stock `.bca` selector report narrows that one step further still: the exact
|
- the global stock `.bca` selector report narrows that one step further still: the exact
|
||||||
`MachineShop.bca` signature (`byte_0xb8 = 0x00`, `byte_0xb9 = 0x80`, `byte_0xba = 0x3f`,
|
`MachineShop.bca` signature (`byte_0xb8 = 0x00`, `byte_0xb9 = 0x80`, `byte_0xba = 0x3f`,
|
||||||
`byte_0xbb = 0x00`) is unique across the checked-in stock corpus. So the current Tier-2
|
`byte_0xbb = 0x00`) is unique across the checked-in stock corpus. So the current Tier-2
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue