Skip to content

Commit ee27a66

Browse files
committed
refactor: show sorted diff as primary output in verify_parity.rs
- Remove ordered diff from main output (it's noise from traversal order) - Sorted diff is the meaningful apple-to-apple comparison - Shows first 5, last 5, and 10 random middle from sorted diff
1 parent 752ab5a commit ee27a66

File tree

1 file changed

+31
-16
lines changed

1 file changed

+31
-16
lines changed

scripts/verify_parity.rs

Lines changed: 31 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -147,25 +147,22 @@ fn main() {
147147

148148
if golden_hashes.sorted_hash == rust_hashes.sorted_hash {
149149
println!("RESULT: FULL OUTPUT MATCH AFTER LINE-SORT NORMALIZATION");
150-
println!(" Exact line order differs, but the complete output line set matches.");
151-
println!();
152-
show_first_ordered_diffs(&golden_baseline_file, &rust_output);
150+
println!(" Exact line order differs (different traversal order), but content matches.");
151+
println!(" This is acceptable — C++ and Rust walk the MFT/tree in different orders.");
153152
std::process::exit(0);
154153
}
155154

156155
println!("RESULT: STRICT FULL OUTPUT MISMATCH");
157-
println!(" Ordered baseline: {}", golden_hashes.ordered_hash);
158-
println!(" Ordered Rust: {}", rust_hashes.ordered_hash);
159156
println!(" Sorted baseline: {}", golden_hashes.sorted_hash);
160157
println!(" Sorted Rust: {}", rust_hashes.sorted_hash);
161158
println!(
162-
" Line count diff: {} (baseline) vs {} (Rust)",
159+
" Line count: {} (baseline) vs {} (Rust)",
163160
golden_hashes.line_count, rust_hashes.line_count
164161
);
165162
println!();
166163

167-
show_first_ordered_diffs(&golden_baseline_file, &rust_output);
168-
println!();
164+
// Show SORTED diffs first — this is the meaningful comparison
165+
// (Ordered diffs are just noise from different traversal order)
169166
show_first_sorted_diffs(&golden_baseline_file, &rust_output);
170167

171168
std::process::exit(1);
@@ -175,7 +172,8 @@ fn main() {
175172
///
176173
/// Supports two directory structures:
177174
/// 1. New: `<base>/drive_<letter>/` (e.g., `/Users/rnio/uffs_data/drive_d/`)
178-
/// 2. Legacy: `<base>/` with files directly in base (e.g., `/Users/rnio/uffs_data/D_mft.bin`)
175+
/// 2. Legacy: `<base>/` with files directly in base (e.g.,
176+
/// `/Users/rnio/uffs_data/D_mft.bin`)
179177
fn resolve_drive_dir(base_dir: &Path, drive_lower: &str) -> PathBuf {
180178
// Try new structure first: base/drive_<letter>/
181179
let new_style = base_dir.join(format!("drive_{}", drive_lower));
@@ -190,8 +188,8 @@ fn find_golden_baseline_file(data_dir: &Path, drive_lower: &str) -> PathBuf {
190188
// Try various naming conventions in order of preference
191189
let candidates = [
192190
format!("golden_{}.txt", drive_lower),
193-
format!("cpp_{}.txt", drive_lower), // C++ baseline output
194-
format!("rust_live_{}.txt", drive_lower), // Live scan output (when comparing offline)
191+
format!("cpp_{}.txt", drive_lower), // C++ baseline output
192+
format!("rust_live_{}.txt", drive_lower), // Live scan output (when comparing offline)
195193
];
196194

197195
for name in &candidates {
@@ -201,7 +199,10 @@ fn find_golden_baseline_file(data_dir: &Path, drive_lower: &str) -> PathBuf {
201199
}
202200
}
203201

204-
eprintln!("ERROR: Golden baseline file not found in {}", data_dir.display());
202+
eprintln!(
203+
"ERROR: Golden baseline file not found in {}",
204+
data_dir.display()
205+
);
205206
eprintln!(" Checked:");
206207
for name in &candidates {
207208
eprintln!(" - {}", name);
@@ -226,7 +227,10 @@ fn print_usage(prog: &str) {
226227
eprintln!("Examples:");
227228
eprintln!(" {} /Users/rnio/uffs_data F --regenerate", prog);
228229
eprintln!(" {} /Users/rnio/uffs_data F --regenerate --tz -8", prog);
229-
eprintln!(" {} /Users/rnio/uffs_data D --rust /tmp/rust_output.txt", prog);
230+
eprintln!(
231+
" {} /Users/rnio/uffs_data D --rust /tmp/rust_output.txt",
232+
prog
233+
);
230234
}
231235

232236
/// Parse --tz argument from command line. Default: -7 (PDT).
@@ -253,7 +257,10 @@ fn regenerate_rust_output(
253257
};
254258

255259
println!("Mode: --regenerate");
256-
println!("Using --tz-offset {} ({}) to match the golden baseline timezone.", tz_offset, tz_label);
260+
println!(
261+
"Using --tz-offset {} ({}) to match the golden baseline timezone.",
262+
tz_offset, tz_label
263+
);
257264
println!();
258265

259266
// Locate MFT file
@@ -492,7 +499,10 @@ fn sha256_for_lines<'a>(lines: impl IntoIterator<Item = &'a str>) -> String {
492499
}
493500

494501
/// Collect all ordered differences between two files.
495-
fn collect_ordered_diffs(file_a: &Path, file_b: &Path) -> Vec<(usize, Option<String>, Option<String>)> {
502+
fn collect_ordered_diffs(
503+
file_a: &Path,
504+
file_b: &Path,
505+
) -> Vec<(usize, Option<String>, Option<String>)> {
496506
let lines_a = read_lines(file_a);
497507
let lines_b = read_lines(file_b);
498508
let max_len = lines_a.len().max(lines_b.len());
@@ -675,7 +685,12 @@ fn show_sampled_lines(lines: &[String], label: &str) {
675685
let middle: Vec<_> = lines[middle_start..middle_end].to_vec();
676686
let sample_count = 10.min(middle.len());
677687
if sample_count > 0 {
678-
println!("\n Random {} from middle ({} label={}):", sample_count, middle.len(), label);
688+
println!(
689+
"\n Random {} from middle ({} label={}):",
690+
sample_count,
691+
middle.len(),
692+
label
693+
);
679694
let mut rng_seed = n as u64;
680695
let mut indices: Vec<usize> = (0..middle.len()).collect();
681696
for i in (1..indices.len()).rev() {

0 commit comments

Comments
 (0)