@@ -64,10 +64,29 @@ public final class ParallelRadixSort {
6464 */
6565 private static final int MINIMUM_THREAD_WORKLOAD = 4001 ;
6666
67- private static int insertionSortThreshold = DEFAULT_INSERTION_SORT_THRESHOLD ;
68- private static int mergesortThreshold = DEFAULT_MERGESORT_THRESHOLD ;
69- private static int threadWorkload = DEFAULT_THREAD_THRESHOLD ;
67+ /**
68+ * The current actual threshold for the insertion sort.
69+ */
70+ private static volatile int insertionSortThreshold =
71+ DEFAULT_INSERTION_SORT_THRESHOLD ;
72+
73+ /**
74+ * The current actual threshold for the mergesort.
75+ */
76+ private static volatile int mergesortThreshold =
77+ DEFAULT_MERGESORT_THRESHOLD ;
7078
79+ /**
80+ * The current actual minimum thread workload in elements.
81+ */
82+ private static volatile int minimumThreadWorkload =
83+ DEFAULT_THREAD_THRESHOLD ;
84+
85+ /**
86+ * Sets the current insertion sort threshold.
87+ *
88+ * @param newInsertionSortThreshold the new insertion sort threshold.
89+ */
7190 public static void setInsertionSortThreshold (
7291 int newInsertionSortThreshold ) {
7392 insertionSortThreshold =
@@ -76,18 +95,28 @@ public static void setInsertionSortThreshold(
7695 MINIMUM_INSERTION_SORT_THRESHOLD );
7796 }
7897
98+ /**
99+ * Sets the current mergesort threshold.
100+ *
101+ * @param newMergesortThreshold the new mergesort threshold.
102+ */
79103 public static void setMergesortThreshold (int newMergesortThreshold ) {
80104 mergesortThreshold =
81105 Math .max (
82106 newMergesortThreshold ,
83107 MINIMUM_MERGESORT_THRESHOLD );
84108 }
85109
86- public static void setThreadWorkload (int newThreadWorkload ) {
87- threadWorkload =
110+ /**
111+ * Sets the current minimum thread workload.
112+ *
113+ * @param newMinimumThreadWorkload the new minimum thread workload.
114+ */
115+ public static void setMinimumThreadWorkload (int newMinimumThreadWorkload ) {
116+ minimumThreadWorkload =
88117 Math .max (
89118 MINIMUM_THREAD_WORKLOAD ,
90- newThreadWorkload );
119+ newMinimumThreadWorkload );
91120 }
92121
93122 public static void parallelSort (int [] array ) {
@@ -125,7 +154,7 @@ public static void parallelSort(int[] array, int fromIndex, int toIndex) {
125154 int threads =
126155 Math .min (
127156 Runtime .getRuntime ().availableProcessors (),
128- rangeLength / threadWorkload );
157+ rangeLength / minimumThreadWorkload );
129158
130159 threads = Math .max (threads , 1 );
131160
@@ -159,6 +188,8 @@ private static void parallelRadixSortImpl(
159188
160189 return ;
161190 }
191+
192+
162193 }
163194
164195 private static void rangeCheck (
@@ -201,18 +232,6 @@ private static void radixSortImpl(int[] source,
201232 int targetFromIndex ,
202233 int rangeLength ,
203234 int recursionDepth ) {
204- //
205- // if (rangeLength <= mergesortThreshold) {
206- // mergesort(
207- // source,
208- // target,
209- // sourceFromIndex,
210- // targetFromIndex,
211- // rangeLength,
212- // recursionDepth);
213- //
214- // return;
215- // }
216235
217236 int [] bucketSizeMap = new int [BUCKETS ];
218237 int [] startIndexMap = new int [BUCKETS ];
@@ -229,15 +248,13 @@ private static void radixSortImpl(int[] source,
229248 bucketSizeMap [bucketIndex ]++;
230249 }
231250
232- //
233251 // Compute starting indices for buckets in the target array. This is
234252 // actually just an accumulated array of bucketSizeMap, such that
235253 // startIndexMap[0] = 0, startIndexMap[1] = bucketSizeMap[0], ...,
236254 // startIndexMap[BUCKETS - 1] = bucketSizeMap[0] + bucketSizeMap[1] +
237255 // ... + bucketSizeMap[BUCKETS - 2].
238256 for (int i = 1 ; i != BUCKETS ; i ++) {
239- startIndexMap [i ] = startIndexMap [i - 1 ]
240- + bucketSizeMap [i - 1 ];
257+ startIndexMap [i ] = startIndexMap [i - 1 ] + bucketSizeMap [i - 1 ];
241258 }
242259
243260 // Insert each element to its own bucket:
@@ -448,4 +465,78 @@ static int getBucketIndex(int element, int recursionDepth) {
448465 * BITS_PER_BYTE ))
449466 & EXTRACT_BYTE_MASK ;
450467 }
468+
469+ private static final class BucketSizeCounterThread extends Thread {
470+
471+ private final int [] localBucketSizeMap = new int [BUCKETS ];
472+ private final int [] array ;
473+ private final int fromIndex ;
474+ private final int toIndex ;
475+ private final int recursionDepth ;
476+
477+ BucketSizeCounterThread (int [] array ,
478+ int fromIndex ,
479+ int toIndex ,
480+ int recursionDepth ) {
481+
482+ this .array = array ;
483+ this .fromIndex = fromIndex ;
484+ this .toIndex = toIndex ;
485+ this .recursionDepth = recursionDepth ;
486+ }
487+
488+ @ Override
489+ public void run () {
490+ for (int i = fromIndex ; i != toIndex ; i ++) {
491+ localBucketSizeMap [getBucketIndex (array [i ], recursionDepth )]++;
492+ }
493+ }
494+
495+ int [] getLocalBucketSizeMap () {
496+ return localBucketSizeMap ;
497+ }
498+ }
499+
500+ private static final class BucketInserterThread extends Thread {
501+
502+ private final int [] source ;
503+ private final int [] target ;
504+ private final int sourceFromIndex ;
505+ private final int targetFromIndex ;
506+ private final int [] startIndexMap ;
507+ private final int [] processedMap ;
508+ private final int rangeLength ;
509+ private final int recursionDepth ;
510+
511+ BucketInserterThread (int [] source ,
512+ int [] target ,
513+ int sourceFromIndex ,
514+ int targetFromIndex ,
515+ int [] startIndexMap ,
516+ int [] processedMap ,
517+ int rangeLength ,
518+ int recursionDepth ) {
519+ this .source = source ;
520+ this .target = target ;
521+ this .sourceFromIndex = sourceFromIndex ;
522+ this .targetFromIndex = targetFromIndex ;
523+ this .startIndexMap = startIndexMap ;
524+ this .processedMap = processedMap ;
525+ this .rangeLength = rangeLength ;
526+ this .recursionDepth = recursionDepth ;
527+ }
528+
529+ @ Override
530+ public void run () {
531+ int sourceToIndex = sourceFromIndex + rangeLength ;
532+
533+ for (int i = sourceFromIndex ; i != sourceToIndex ; i ++) {
534+ int datum = source [i ];
535+ int bucketKey = getBucketIndex (datum , recursionDepth );
536+
537+ target [targetFromIndex + startIndexMap [bucketKey ] +
538+ processedMap [bucketKey ]++] = datum ;
539+ }
540+ }
541+ }
451542}
0 commit comments