@@ -348,8 +348,10 @@ mod test {
348
348
fn test_external_sorter ( #[ case] reversed : bool ) {
349
349
let input_sorted = 0 ..100 ;
350
350
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) ) ) ;
353
355
354
356
let sorter: ExternalSorter < i32 , _ > = ExternalSorterBuilder :: new ( )
355
357
. with_buffer ( LimitedBufferBuilder :: new ( 8 , true ) )
@@ -376,4 +378,43 @@ mod test {
376
378
377
379
assert_eq ! ( actual_result, expected_result)
378
380
}
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
+ }
379
420
}
0 commit comments