@@ -348,8 +348,10 @@ mod test {
348348 fn test_external_sorter ( #[ case] reversed : bool ) {
349349 let input_sorted = 0 ..100 ;
350350
351- let mut input: Vec < Result < i32 , io:: Error > > = Vec :: from_iter ( input_sorted. clone ( ) . map ( |item| Ok ( item) ) ) ;
352- input. shuffle ( & mut rand:: thread_rng ( ) ) ;
351+ let mut input_shuffled = Vec :: from_iter ( input_sorted. clone ( ) ) ;
352+ input_shuffled. shuffle ( & mut rand:: thread_rng ( ) ) ;
353+
354+ let input: Vec < Result < i32 , io:: Error > > = Vec :: from_iter ( input_shuffled. into_iter ( ) . map ( |item| Ok ( item) ) ) ;
353355
354356 let sorter: ExternalSorter < i32 , _ > = ExternalSorterBuilder :: new ( )
355357 . with_buffer ( LimitedBufferBuilder :: new ( 8 , true ) )
@@ -376,4 +378,43 @@ mod test {
376378
377379 assert_eq ! ( actual_result, expected_result)
378380 }
381+
382+ #[ rstest]
383+ #[ case( false ) ]
384+ #[ case( true ) ]
385+ fn test_external_sorter_stability ( #[ case] reversed : bool ) {
386+ let input_sorted = ( 0 ..20 ) . flat_map ( |x|( 0 ..5 ) . map ( move |y| ( x, y) ) ) ;
387+
388+ let mut input_shuffled = Vec :: from_iter ( input_sorted. clone ( ) ) ;
389+ input_shuffled. shuffle ( & mut rand:: thread_rng ( ) ) ;
390+ // sort input by the second field to check sorting stability
391+ input_shuffled. sort_by ( |a : & ( i32 , i32 ) , b : & ( i32 , i32 ) | if reversed { a. 1 . cmp ( & b. 1 ) . reverse ( ) } else { a. 1 . cmp ( & b. 1 ) } ) ;
392+
393+ let input: Vec < Result < ( i32 , i32 ) , io:: Error > > = Vec :: from_iter ( input_shuffled. into_iter ( ) . map ( |item| Ok ( item) ) ) ;
394+
395+ let sorter: ExternalSorter < ( i32 , i32 ) , _ > = ExternalSorterBuilder :: new ( )
396+ . with_buffer ( LimitedBufferBuilder :: new ( 8 , true ) )
397+ . with_threads_number ( 2 )
398+ . with_tmp_dir ( Path :: new ( "./" ) )
399+ . build ( )
400+ . unwrap ( ) ;
401+
402+ let compare = if reversed {
403+ |a : & ( i32 , i32 ) , b : & ( i32 , i32 ) | a. 0 . cmp ( & b. 0 ) . reverse ( )
404+ } else {
405+ |a : & ( i32 , i32 ) , b : & ( i32 , i32 ) | a. 0 . cmp ( & b. 0 )
406+ } ;
407+
408+ let result = sorter. sort_by ( input, compare) . unwrap ( ) ;
409+
410+ let actual_result: Result < Vec < ( i32 , i32 ) > , _ > = result. collect ( ) ;
411+ let actual_result = actual_result. unwrap ( ) ;
412+ let expected_result = if reversed {
413+ Vec :: from_iter ( input_sorted. clone ( ) . rev ( ) )
414+ } else {
415+ Vec :: from_iter ( input_sorted. clone ( ) )
416+ } ;
417+
418+ assert_eq ! ( actual_result, expected_result)
419+ }
379420}
0 commit comments