@@ -311,24 +311,16 @@ fn show_diff(cfg: &Config, drive: &str, cpp: &[String], rust: &[String],
311311 println ! ( " C++ SHA256: {}" , cpp_hash) ;
312312 println ! ( " Rust SHA256: {}" , rust_hash) ;
313313
314+ // Show sorted side-by-side comparison (most useful for debugging)
315+ let diff_count = show_sorted_side_by_side_diffs ( cpp, rust) ;
316+
317+ // Also compute set-based diffs for the file output
314318 let cpp_set: HashSet < & str > = cpp. iter ( ) . map ( |s| s. as_str ( ) ) . collect ( ) ;
315319 let rust_set: HashSet < & str > = rust. iter ( ) . map ( |s| s. as_str ( ) ) . collect ( ) ;
316320
317321 let only_cpp: Vec < _ > = cpp. iter ( ) . filter ( |l| !rust_set. contains ( l. as_str ( ) ) ) . collect ( ) ;
318322 let only_rust: Vec < _ > = rust. iter ( ) . filter ( |l| !cpp_set. contains ( l. as_str ( ) ) ) . collect ( ) ;
319323
320- println ! ( "\n Only in C++: {}" , only_cpp. len( ) ) ;
321- println ! ( " Only in Rust: {}" , only_rust. len( ) ) ;
322-
323- if !only_cpp. is_empty ( ) {
324- println ! ( "\n C++ only (first 5):" ) ;
325- for l in only_cpp. iter ( ) . take ( 5 ) { println ! ( " < {}" , l) ; }
326- }
327- if !only_rust. is_empty ( ) {
328- println ! ( "\n Rust only (first 5):" ) ;
329- for l in only_rust. iter ( ) . take ( 5 ) { println ! ( " > {}" , l) ; }
330- }
331-
332324 // Write detailed diff to file
333325 let diff_path = cfg. out_dir . join ( format ! ( "parity_diff_{}_{}.txt" , drive. to_lowercase( ) , ts) ) ;
334326 if let Ok ( mut f) = fs:: File :: create ( & diff_path) {
@@ -342,7 +334,88 @@ fn show_diff(cfg: &Config, drive: &str, cpp: &[String], rust: &[String],
342334 println ! ( "\n Diff file: {}" , diff_path. display( ) ) ;
343335 }
344336
345- only_cpp. len ( ) + only_rust. len ( )
337+ diff_count
338+ }
339+
340+ /// Show side-by-side comparison of DIFFERENT lines from sorted files.
341+ /// Only shows lines where C++ != Rust. First 5 diffs, last 5 diffs, 10 random from middle.
342+ fn show_sorted_side_by_side_diffs ( cpp_sorted : & [ String ] , rust_sorted : & [ String ] ) -> usize {
343+ let n = cpp_sorted. len ( ) . min ( rust_sorted. len ( ) ) ;
344+ if n == 0 {
345+ println ! ( "\n No lines to compare." ) ;
346+ return 0 ;
347+ }
348+
349+ // Collect indices of lines that differ
350+ let diff_indices: Vec < usize > = ( 0 ..n)
351+ . filter ( |& i| cpp_sorted[ i] != rust_sorted[ i] )
352+ . collect ( ) ;
353+
354+ println ! ( "\n === SORTED SIDE-BY-SIDE COMPARISON (differences only) ===" ) ;
355+ println ! ( " C++ lines: {}" , cpp_sorted. len( ) ) ;
356+ println ! ( " Rust lines: {}" , rust_sorted. len( ) ) ;
357+ println ! ( " Lines that differ: {}" , diff_indices. len( ) ) ;
358+
359+ if diff_indices. is_empty ( ) {
360+ println ! ( "\n ✅ All lines match!" ) ;
361+ return 0 ;
362+ }
363+
364+ let total_diffs = diff_indices. len ( ) ;
365+ let first_n = 5 . min ( total_diffs) ;
366+ let last_n = 5 . min ( total_diffs) ;
367+
368+ // First 5 differences
369+ println ! ( "\n --- FIRST {} DIFFERENCES ---" , first_n) ;
370+ for & idx in diff_indices. iter ( ) . take ( first_n) {
371+ println ! ( " Line {}:" , idx + 1 ) ;
372+ println ! ( " C++: {}" , cpp_sorted[ idx] ) ;
373+ println ! ( " RUST: {}" , rust_sorted[ idx] ) ;
374+ }
375+
376+ // Last 5 differences (if different from first 5)
377+ if total_diffs > 10 {
378+ let last_start = total_diffs. saturating_sub ( last_n) ;
379+ println ! ( "\n --- LAST {} DIFFERENCES ---" , last_n) ;
380+ for & idx in diff_indices. iter ( ) . skip ( last_start) {
381+ println ! ( " Line {}:" , idx + 1 ) ;
382+ println ! ( " C++: {}" , cpp_sorted[ idx] ) ;
383+ println ! ( " RUST: {}" , rust_sorted[ idx] ) ;
384+ }
385+ }
386+
387+ // 10 random from middle differences
388+ if total_diffs > 10 {
389+ let middle_start = first_n;
390+ let middle_end = total_diffs. saturating_sub ( last_n) ;
391+ if middle_end > middle_start {
392+ let middle_diff_indices: Vec < usize > = diff_indices[ middle_start..middle_end] . to_vec ( ) ;
393+ let sample_count = 10 . min ( middle_diff_indices. len ( ) ) ;
394+
395+ println ! (
396+ "\n --- {} RANDOM DIFFERENCES FROM MIDDLE ({} middle diffs) ---" ,
397+ sample_count,
398+ middle_diff_indices. len( )
399+ ) ;
400+
401+ // Deterministic shuffle using LCG
402+ let mut rng_seed = total_diffs as u64 ;
403+ let mut shuffled: Vec < usize > = middle_diff_indices;
404+ for i in ( 1 ..shuffled. len ( ) ) . rev ( ) {
405+ rng_seed = rng_seed. wrapping_mul ( 6364136223846793005 ) . wrapping_add ( 1 ) ;
406+ let j = ( rng_seed as usize ) % ( i + 1 ) ;
407+ shuffled. swap ( i, j) ;
408+ }
409+
410+ for & idx in shuffled. iter ( ) . take ( sample_count) {
411+ println ! ( " Line {}:" , idx + 1 ) ;
412+ println ! ( " C++: {}" , cpp_sorted[ idx] ) ;
413+ println ! ( " RUST: {}" , rust_sorted[ idx] ) ;
414+ }
415+ }
416+ }
417+
418+ total_diffs
346419}
347420
348421fn print_summary ( results : & [ DriveResult ] ) {
0 commit comments