@@ -366,17 +366,23 @@ where
366
366
A : Ord + Clone ,
367
367
S : DataMut < Elem = A > ,
368
368
{
369
- if indexes. is_empty ( ) {
370
- return IndexMap :: new ( ) ;
371
- }
372
-
373
- // Since `!indexes.is_empty()` and indexes must be in-bounds, `array` must
374
- // be non-empty.
375
- let mut values = vec ! [ array[ 0 ] . clone( ) ; indexes. len( ) ] ;
376
- _get_many_from_sorted_mut_unchecked ( array. view_mut ( ) , & mut indexes. to_owned ( ) , & mut values) ;
369
+ match indexes. len ( ) {
370
+ 0 => IndexMap :: new ( ) ,
371
+ 1 => IndexMap :: from ( [ ( indexes[ 0 ] , array. get_from_sorted_mut ( indexes[ 0 ] ) ) ] ) ,
372
+ _ => {
373
+ // Since `!indexes.is_empty()` and indexes must be in-bounds, `array` must
374
+ // be non-empty.
375
+ let mut values = vec ! [ array[ 0 ] . clone( ) ; indexes. len( ) ] ;
376
+ _get_many_from_sorted_mut_unchecked (
377
+ array. view_mut ( ) ,
378
+ & mut indexes. to_owned ( ) ,
379
+ & mut values,
380
+ ) ;
377
381
378
- // We convert the vector to a more search-friendly `IndexMap`.
379
- indexes. iter ( ) . cloned ( ) . zip ( values. into_iter ( ) ) . collect ( )
382
+ // We convert the vector to a more search-friendly `IndexMap`.
383
+ indexes. iter ( ) . cloned ( ) . zip ( values. into_iter ( ) ) . collect ( )
384
+ }
385
+ }
380
386
}
381
387
382
388
/// This is the recursive portion of `get_many_from_sorted_mut_unchecked`.
@@ -420,81 +426,10 @@ fn _get_many_from_sorted_mut_unchecked<A>(
420
426
// Sorted sample of 5 equally spaced elements around the center.
421
427
let mut sample = [ 0 ; 5 ] ;
422
428
sample_mut ( & mut array, & mut sample) ;
423
- let ( lower_index, upper_index) = if indexes. len ( ) == 1 {
424
- // Adapt pivot sampling to relative sought rank and switch from dual-pivot to single-pivot
425
- // partitioning for extreme sought ranks.
426
- let sought_rank = indexes[ 0 ] as f64 / n as f64 ;
427
- if ( 0.036 ..=0.964 ) . contains ( & sought_rank) {
428
- if sought_rank <= 0.5 {
429
- if sought_rank <= 0.153 {
430
- ( 0 , 1 ) // (0, 0, 3)
431
- } else {
432
- ( 0 , 2 ) // (0, 1, 2)
433
- }
434
- } else {
435
- if sought_rank <= 0.847 {
436
- ( 2 , 4 ) // (2, 1, 0)
437
- } else {
438
- ( 3 , 4 ) // (3, 0, 0)
439
- }
440
- }
441
- } else {
442
- let pivot_index = if sought_rank <= 0.5 {
443
- 0 // (0, 4)
444
- } else {
445
- 4 // (4, 0)
446
- } ;
447
-
448
- // We partition the array with respect to the pivot value. The pivot value moves to the
449
- // new `pivot_index`.
450
- //
451
- // Elements strictly less than the pivot value have indexes < `pivot_index`.
452
- //
453
- // Elements greater than or equal the pivot value have indexes > `pivot_index`.
454
- let pivot_index = array. partition_mut ( sample[ pivot_index] ) ;
455
- let ( found_exact, split_index) = match indexes. binary_search ( & pivot_index) {
456
- Ok ( index) => ( true , index) ,
457
- Err ( index) => ( false , index) ,
458
- } ;
459
- let ( lower_indexes, upper_indexes) = indexes. split_at_mut ( split_index) ;
460
- let ( lower_values, upper_values) = values. split_at_mut ( split_index) ;
461
- let ( upper_indexes, upper_values) = if found_exact {
462
- upper_values[ 0 ] = array[ pivot_index] . clone ( ) ; // Write exactly found value.
463
- ( & mut upper_indexes[ 1 ..] , & mut upper_values[ 1 ..] )
464
- } else {
465
- ( upper_indexes, upper_values)
466
- } ;
467
-
468
- // We search recursively for the values corresponding to indexes strictly less than
469
- // `pivot_index` in the lower partition.
470
- maybe_grow ( RED_ZONE , STACK_SIZE , || {
471
- _get_many_from_sorted_mut_unchecked (
472
- array. slice_axis_mut ( Axis ( 0 ) , Slice :: from ( ..pivot_index) ) ,
473
- lower_indexes,
474
- lower_values,
475
- ) ;
476
- } ) ;
477
-
478
- // We search recursively for the values corresponding to indexes greater than or equal
479
- // `pivot_index` in the upper partition. Since only the upper partition of the array is
480
- // passed in, the indexes need to be shifted by length of the lower partition.
481
- upper_indexes. iter_mut ( ) . for_each ( |x| * x -= pivot_index + 1 ) ;
482
- maybe_grow ( RED_ZONE , STACK_SIZE , || {
483
- _get_many_from_sorted_mut_unchecked (
484
- array. slice_axis_mut ( Axis ( 0 ) , Slice :: from ( pivot_index + 1 ..) ) ,
485
- upper_indexes,
486
- upper_values,
487
- ) ;
488
- } ) ;
489
-
490
- return ;
491
- }
492
- } else {
493
- // Since there is no single sought rank to adapt pivot sampling to, the recommended skewed
494
- // pivot sampling of dual-pivot Quicksort is used in the assumption that multiple indexes
495
- // change characteristics from Quickselect towards Quicksort.
496
- ( 0 , 2 ) // (0, 1, 2)
497
- } ;
429
+ // Since there is no single sought rank to adapt pivot sampling to, the recommended skewed
430
+ // pivot sampling of dual-pivot Quicksort is used in the assumption that multiple indexes
431
+ // change characteristics from Quickselect towards Quicksort.
432
+ let ( lower_index, upper_index) = ( 0 , 2 ) ; // (0, 1, 2)
498
433
499
434
// We partition the array with respect to the two pivot values. The pivot values move to the new
500
435
// `lower_index` and `upper_index`.
0 commit comments