55import java .util .Random ;
66
77/**
8- *
8+ * This class provides the method for parallel sorting of {@code int} arrays.
9+ * The underlying algorithm is a parallel MSD (most significant digit) radix
10+ * sort. At each iteration, only a single byte is considered so that the number
11+ * of buckets is 256. This implementation honours the sign bit so that the
12+ * result of parallel radix sorting is the same as in
13+ * {@link java.util.Arrays.parallelSort(int[])}.
14+ *
915 * @author Rodion "rodde" Efremov
1016 * @version 1.6 (Jun 3, 2023)
1117 * @since 1.6 (Jun 3, 2023)
@@ -67,7 +73,7 @@ public final class ParallelRadixSort {
6773 /**
6874 * Minimum thread workload.
6975 */
70- private static final int MINIMUM_THREAD_WORKLOAD = 4001 ;
76+ private static final int MINIMUM_THREAD_WORKLOAD = 1 ;
7177
7278 /**
7379 * The current actual threshold for the insertion sort.
@@ -124,10 +130,22 @@ public static void setMinimumThreadWorkload(int newMinimumThreadWorkload) {
124130 newMinimumThreadWorkload );
125131 }
126132
133+ /**
134+ * Sorts the entire input array into non-decreasing order.
135+ *
136+ * @param array the array to sort.
137+ */
127138 public static void parallelSort (int [] array ) {
128139 parallelSort (array , 0 , array .length );
129140 }
130141
142+ /**
143+ * Sorts the range {@code array[fromIndex], ..., array[toIndex - 1]}.
144+ *
145+ * @param array the array holding the target range to sort.
146+ * @param fromIndex the starting, inclusive index of the range to sort.
147+ * @param toIndex the ending, exclusive index of the range to sort.
148+ */
131149 public static void parallelSort (int [] array , int fromIndex , int toIndex ) {
132150 rangeCheck (array .length , fromIndex , toIndex );
133151
@@ -163,14 +181,24 @@ public static void parallelSort(int[] array, int fromIndex, int toIndex) {
163181
164182 threads = Math .max (threads , 1 );
165183
166- parallelRadixSortImpl (
167- array ,
168- buffer ,
169- fromIndex ,
170- 0 ,
171- rangeLength ,
172- 0 ,
173- threads );
184+ if (threads == 1 ) {
185+ radixSortImpl (
186+ array ,
187+ buffer ,
188+ fromIndex ,
189+ 0 ,
190+ rangeLength ,
191+ 0 );
192+ } else {
193+ parallelRadixSortImpl (
194+ array ,
195+ buffer ,
196+ fromIndex ,
197+ 0 ,
198+ rangeLength ,
199+ 0 ,
200+ threads );
201+ }
174202 }
175203
176204 private static void parallelRadixSortImpl (
@@ -182,18 +210,6 @@ private static void parallelRadixSortImpl(
182210 int recursionDepth ,
183211 int threads ) {
184212
185- if (threads == 1 ) {
186- radixSortImpl (
187- source ,
188- target ,
189- sourceFromIndex ,
190- targetFromIndex ,
191- rangeLength ,
192- recursionDepth );
193-
194- return ;
195- }
196-
197213 int startIndex = sourceFromIndex ;
198214 int subrangeLength = rangeLength / threads ;
199215
@@ -294,13 +310,16 @@ private static void parallelRadixSortImpl(
294310 new BucketInserterThread (
295311 source ,
296312 target ,
297- sourceStartIndex += subrangeLength ,
298- targetStartIndex += subrangeLength ,
313+ sourceStartIndex ,
314+ targetStartIndex ,
299315 startIndexMap ,
300316 processedMaps [i ],
301317 subrangeLength ,
302318 recursionDepth );
303319
320+ sourceStartIndex += subrangeLength ;
321+ targetStartIndex += subrangeLength ;
322+
304323 bucketInserterThread .start ();
305324 bucketInserterThreads [i ] = bucketInserterThread ;
306325 }
@@ -318,10 +337,10 @@ private static void parallelRadixSortImpl(
318337
319338 // Run the last, rightmost bucket inserter thread in this thread:
320339 lastBucketInserterThread .run ();
321- bucketInserterThreads [threads - 1 ] = lastBucketInserterThread ;
340+ bucketInserterThreads [spawnDegree - 1 ] = lastBucketInserterThread ;
322341
323342 // Join all the spawned bucket inserter threads:
324- for (int i = 0 ; i != threads - 1 ; i ++) {
343+ for (int i = 0 ; i != spawnDegree - 1 ; i ++) {
325344 BucketInserterThread bucketInserterThread =
326345 bucketInserterThreads [i ];
327346
0 commit comments