4949 *
5050 * @since 1.7 * 14
5151 */
52- final class DualPivotQuicksort_6K_4 {
52+ final class DualPivotQuicksort_6K_5d2 {
5353
5454 /**
5555 * Prevents instantiation.
@@ -586,108 +586,104 @@ private static void insertionSort(int[] a, int low, int high) {
586586 // TODO add javadoc
587587// private
588588 static void radixSort (Sorter sorter , int [] a , int low , int high ) {
589- //System.out.println(" Radix !!!");
590589 int [] count1 = new int [256 ];
591590 int [] count2 = new int [256 ];
592591 int [] count3 = new int [256 ];
593592 int [] count4 = new int [256 ];
594593
595594 for (int i = low ; i < high ; ++i ) {
596- count1 [ a [i ] & 0xFF ]--;
597- count2 [(a [i ] >>> 8 ) & 0xFF ]--;
598- count3 [(a [i ] >>> 16 ) & 0xFF ]--;
599- count4 [(a [i ] >>> 24 ) ^ 0x80 ]--;
595+ count1 [ a [i ] & 0xFF ]--;
596+ count2 [(a [i ] >>> 8 ) & 0xFF ]--;
597+ count3 [(a [i ] >>> 16 ) & 0xFF ]--;
598+ count4 [(a [i ] >>> 24 ) ^ 0x80 ]--;
600599 }
601- boolean skipByte4 = skipByte ( count4 , low - high , high , true );
602- boolean skipByte3 = skipByte ( count3 , low - high , high , skipByte4 );
603- boolean skipByte2 = skipByte ( count2 , low - high , high , skipByte3 );
604- boolean skipByte1 = skipByte ( count1 , low - high , high , skipByte2 );
600+ boolean passLevel1 = passLevel ( count1 , low - high , high );
601+ boolean passLevel2 = passLevel ( count2 , low - high , high );
602+ boolean passLevel3 = passLevel ( count3 , low - high , high );
603+ boolean passLevel4 = passLevel ( count4 , low - high , high );
605604
606- if (skipByte1 ) {
607- //Main.check(a, low, high - 1); // todo
605+ if (!passLevel1 && !passLevel2 && !passLevel3 && !passLevel4 ) {
608606 return ;
609607 }
610- // int xorA = Main.getXor(a, low, high);
611-
612608 int [] b ; int offset = low ;
613609
614610 if (sorter == null || (b = (int []) sorter .b ) == null ) {
615611 b = new int [high - low ];
616612 } else {
617613 offset = sorter .offset ;
618- //System.out.println(" !!!! offset: " + offset);
619614 }
620615 int start = low - offset ;
621616 int last = high - offset ;
622-
623-
617+
624618 // 1 todo process LSD
625- for (int i = low ; i < high ; ++i ) {
626- b [count1 [a [i ] & 0xFF ]++ - offset ] = a [i ];
627- }
628-
629- // if (xorA != Main.getXor(a, low, high)) System.out.println("6K_4 1 xor changed");
630-
631- if (skipByte2 ) {
632- System .arraycopy (b , start , a , low , high - low );
633- //Main.check(a, low, high - 1); // todo
634- return ;
619+ if (passLevel1 ) {
620+ for (int i = low ; i < high ; ++i ) {
621+ b [count1 [a [i ] & 0xFF ]++ - offset ] = a [i ];
622+ }
635623 }
636624
637625 // 2
638- for (int i = start ; i < last ; ++i ) {
639- a [count2 [(b [i ] >> 8 ) & 0xFF ]++] = b [i ];
640- }
641-
642- // if (xorA != Main.getXor(a, low, high)) System.out.println("6K_4 2 xor changed");
643-
644- if (skipByte3 ) {
645- //Main.check(a, low, high - 1); // todo
646- return ;
626+ if (passLevel2 ) {
627+ if (passLevel1 ) {
628+ for (int i = start ; i < last ; ++i ) {
629+ a [count2 [(b [i ] >> 8 ) & 0xFF ]++] = b [i ];
630+ }
631+ } else {
632+ for (int i = low ; i < high ; ++i ) {
633+ b [count2 [(a [i ] >> 8 ) & 0xFF ]++ - offset ] = a [i ];
634+ }
635+ }
647636 }
648637
649638 // 3
650- for (int i = low ; i < high ; ++i ) {
651- b [count3 [(a [i ] >> 16 ) & 0xFF ]++ - offset ] = a [i ];
639+ if (passLevel3 ) {
640+ if (passLevel1 ^ passLevel2 ) {
641+ for (int i = start ; i < last ; ++i ) {
642+ a [count3 [(b [i ] >> 16 ) & 0xFF ]++] = b [i ];
643+ }
644+ } else {
645+ for (int i = low ; i < high ; ++i ) {
646+ b [count3 [(a [i ] >> 16 ) & 0xFF ]++ - offset ] = a [i ];
647+ }
648+ }
652649 }
653650
654- // if (xorA != Main.getXor(a, low, high)) System.out.println("6K_4 3 xor changed");
655-
656- if (skipByte4 ) {
657- System .arraycopy (b , start , a , low , high - low );
658- //Main.check(a, low, high - 1); // todo
659- return ;
651+ // 4
652+ if (passLevel4 ) {
653+ if (passLevel1 ^ passLevel2 ^ passLevel3 ) {
654+ for (int i = start ; i < last ; ++i ) {
655+ a [count4 [(b [i ] >>> 24 ) ^ 0x80 ]++] = b [i ];
656+ }
657+ } else {
658+ for (int i = low ; i < high ; ++i ) {
659+ b [count4 [(a [i ] >>> 24 ) ^ 0x80 ]++ - offset ] = a [i ];
660+ }
661+ }
660662 }
661663
662- // if (xorA != Main.getXor(a, low, high)) System.out.println("6K_4 4 xor changed");
663- // 4
664- for (int i = start ; i < last ; ++i ) {
665- a [count4 [(b [i ] >>> 24 ) ^ 0x80 ]++] = b [i ];
664+ if (passLevel1 ^ passLevel2 ^ passLevel3 ^ passLevel4 ) {
665+ System .arraycopy (b , low - offset , a , low , high - low );
666666 }
667- // if (xorA != Main.getXor(a, low, high)) System.out.println("6K_4 5 xor changed");
668- //Main.check(a, low, high - 1); // todo
669667 }
670668
671669 // TODO: add javadoc
672- private static boolean skipByte (int [] count , int total , int high , boolean prevSkip ) {
673- if (prevSkip ) {
674- for (int c : count ) {
675- if (c == 0 ) {
676- continue ;
677- }
678- if (c == total ) {
679- return true ;
680- }
681- break ;
670+ private static boolean passLevel (int [] count , int total , int high ) {
671+ for (int c : count ) {
672+ if (c == 0 ) {
673+ continue ;
674+ }
675+ if (c == total ) {
676+ return false ;
682677 }
678+ break ;
683679 }
684680 // todo create historgam
685681 count [255 ] += high ;
686682
687683 for (int i = 255 ; i > 0 ; --i ) {
688684 count [i - 1 ] += count [i ];
689685 }
690- return false ;
686+ return true ;
691687 }
692688
693689 /**
@@ -789,7 +785,6 @@ private static boolean tryMergeRuns(Sorter sorter, int[] a, int low, int size) {
789785 */
790786 if (run == null ) {
791787 if (k == high ) {
792-
793788 /*
794789 * The array is monotonous sequence,
795790 * and therefore already sorted.
@@ -798,7 +793,6 @@ private static boolean tryMergeRuns(Sorter sorter, int[] a, int low, int size) {
798793 }
799794
800795 if (k - low < MIN_FIRST_RUN_SIZE ) {
801-
802796 /*
803797 * The first run is too small
804798 * to proceed with scanning.
@@ -809,10 +803,9 @@ private static boolean tryMergeRuns(Sorter sorter, int[] a, int low, int size) {
809803 run = new int [((size >> 10 ) | 0x7F ) & 0x3FF ];
810804 run [0 ] = low ;
811805
812- } else if (a [last - 1 ] > a [last ]) {
806+ } else if (a [last - 1 ] > a [last ]) { // Can't join with previous run
813807
814808 if (count > (k - low ) >> MIN_FIRST_RUNS_FACTOR ) {
815-
816809 /*
817810 * The first runs are not long
818811 * enough to continue scanning.
@@ -821,22 +814,27 @@ private static boolean tryMergeRuns(Sorter sorter, int[] a, int low, int size) {
821814 }
822815
823816 if (++count == MAX_RUN_CAPACITY ) {
824-
825817 /*
826818 * Array is not highly structured.
827819 */
828820 return false ;
829821 }
830822
831823 if (count == run .length ) {
832-
833824 /*
834825 * Increase capacity of index array.
835826 */
836827 run = Arrays .copyOf (run , count << 1 );
837828 }
838829 }
839830 run [count ] = (last = k );
831+
832+ if (++k == high ) {
833+ /*
834+ * There is a single-element run at the end.
835+ */
836+ --k ;
837+ }
840838 }
841839
842840 /*
0 commit comments