ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/main/java/util/TimSort.java
Revision: 1.1
Committed: Tue Sep 1 01:40:03 2009 UTC (14 years, 8 months ago) by jsr166
Branch: MAIN
Log Message:
Import TimSort from Josh Bloch

File Contents

# Content
1 /*
2 * Copyright (C) 2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 import java.util.*;
18
19 /**
20 * A stable, adaptive, iterative mergesort that requires far fewer than
21 * n lg(n) comparisons when running on partially sorted arrays, while
22 * offering performance comparable to a traditional mergesort when run
23 * on random arrays. Like all proper mergesorts, this sort is stable and
24 * runs O(n log n) time (worst case). In the worst case, this sort requires
25 * temporary storage space for n/2 object references; in the best case,
26 * it requires only a small constant amount of space.
27 *
28 * This implementation was adapted from Tim Peters's list sort for
29 * Python, which is described in detail here:
30 *
31 * http://svn.python.org/projects/python/trunk/Objects/listsort.txt
32 *
33 * Tim's C code may be found here:
34 *
35 * http://svn.python.org/projects/python/trunk/Objects/listobject.c
36 *
37 * The underlying techniques are described in this paper (and may have
38 * even earlier origins):
39 *
40 * "Optimistic Sorting and Information Theoretic Complexity"
41 * Peter McIlroy
42 * SODA (Fourth Annual ACM-SIAM Symposium on Discrete Algorithms),
43 * pp 467-474, Austin, Texas, 25-27 January 1993.
44 *
45 * While the API to this class consists solely of static methods, it is
46 * (privately) instantiable; a TimSort instance holds the state of an ongoing
47 * sort, assuming the input array is large enough to warrant the full-blown
48 * TimSort. Small arrays are sorted in place, using a binary insertion sort.
49 */
50 class TimSort<T> {
51 /**
52 * This is the minimum sized sequence that will be merged. Shorter
53 * sequences will be lengthened by calling binarySort. If the entire
54 * array is less than this length, no merges will be performed.
55 *
56 * This constant should be a power of two. It was 64 in Tim Peter's C
57 * implementation, but 32 was empirically determined to work better in
58 * this implementation. In the unlikely event that you set this constant
59 * to be a number that's not a power of two, you'll need to change the
60 * {@link #minRunLength} computation.
61 *
62 * If you decrease this constant, you must change the stackLen
63 * computation in the TimSort constructor, or you risk an
64 * ArrayOutOfBounds exception. See listsort.txt for a discussion
65 * of the minimum stack length required as a function of the length
66 * of the array being sorted and the minimum merge sequence length.
67 */
68 private static final int MIN_MERGE = 32;
69
70 /**
71 * The array being sorted.
72 */
73 private final T[] a;
74
75 /**
76 * The comparator for this sort.
77 */
78 private final Comparator<? super T> c;
79
80 /**
81 * When we get into galloping mode, we stay there until both runs win less
82 * often than MIN_GALLOP consecutive times.
83 */
84 private static final int MIN_GALLOP = 7;
85
86 /**
87 * This controls when we get *into* galloping mode. It is initialized
88 * to MIN_GALLOP. The mergeLo and mergeHi methods nudge it higher for
89 * random data, and lower for highly structured data.
90 */
91 private int minGallop = MIN_GALLOP;
92
93 /**
94 * Maximum initial size of tmp array, which is used for merging. The array
95 * can grow to accommodate demand.
96 *
97 * Unlike Tim's original C version, we do not allocate this much storage
98 * when sorting smaller arrays. This change was required for performance.
99 */
100 private static final int INITIAL_TMP_STORAGE_LENGTH = 256;
101
102 /**
103 * Temp storage for merges.
104 */
105 private T[] tmp; // Actual runtime type will be Object[], regardless of T
106
107 /**
108 * A stack of pending runs yet to be merged. Run i starts at
109 * address base[i] and extends for len[i] elements. It's always
110 * true (so long as the indices are in bounds) that:
111 *
112 * runBase[i] + runLen[i] == runBase[i + 1]
113 *
114 * so we could cut the storage for this, but it's a minor amount,
115 * and keeping all the info explicit simplifies the code.
116 */
117 private int stackSize = 0; // Number of pending runs on stack
118 private final int[] runBase;
119 private final int[] runLen;
120
121 /**
122 * Creates a TimSort instance to maintain the state of an ongoing sort.
123 *
124 * @param a the array to be sorted
125 * @param c the comparator to determine the order of the sort
126 */
127 private TimSort(T[] a, Comparator<? super T> c) {
128 this.a = a;
129 this.c = c;
130
131 // Allocate temp storage (which may be increased later if necessary)
132 int len = a.length;
133 @SuppressWarnings({"unchecked", "UnnecessaryLocalVariable"})
134 T[] newArray = (T[]) new Object[len < 2 * INITIAL_TMP_STORAGE_LENGTH ?
135 len >>> 1 : INITIAL_TMP_STORAGE_LENGTH];
136 tmp = newArray;
137
138 /*
139 * Allocate runs-to-be-merged stack (which cannot be expanded). The
140 * stack length requirements are described in listsort.txt. The C
141 * version always uses the same stack length (85), but this was
142 * measured to be too expensive when sorting "mid-sized" arrays (e.g.,
143 * 100 elements) in Java. Therefore, we use smaller (but sufficiently
144 * large) stack lengths for smaller arrays. The "magic numbers" in the
145 * computation below must be changed if MIN_MERGE is decreased. See
146 * the MIN_MERGE declaration above for more information.
147 */
148 int stackLen = (len < 120 ? 5 :
149 len < 1542 ? 10 :
150 len < 119151 ? 19 : 40);
151 runBase = new int[stackLen];
152 runLen = new int[stackLen];
153 }
154
155 /*
156 * The next two methods (which are package private and static) constitute
157 * the entire API of this class. Each of these methods obeys the contract
158 * of the public method with the same signature in java.util.Arrays.
159 */
160
161 static <T> void sort(T[] a, Comparator<? super T> c) {
162 sort(a, 0, a.length, c);
163 }
164
165 static <T> void sort(T[] a, int lo, int hi, Comparator<? super T> c) {
166 if (c == null) {
167 Arrays.sort(a, lo, hi);
168 return;
169 }
170
171 rangeCheck(a.length, lo, hi);
172 int nRemaining = hi - lo;
173 if (nRemaining < 2)
174 return; // Arrays of size 0 and 1 are always sorted
175
176 // If array is small, do a "mini-TimSort" with no merges
177 if (nRemaining < MIN_MERGE) {
178 int initRunLen = countRunAndMakeAscending(a, lo, nRemaining, c);
179 binarySort(a, lo, hi, lo + initRunLen, c);
180 return;
181 }
182
183 /**
184 * March over the array once, left to right, finding natural runs,
185 * extending short natural runs to minRun elements, and merging runs
186 * to maintain stack invariant.
187 */
188 TimSort<T> ts = new TimSort<T>(a, c);
189 int minRun = minRunLength(nRemaining);
190 do {
191 // Identify next run
192 int runLen = countRunAndMakeAscending(a, lo, hi, c);
193
194 // If run is short, extend to min(minRun, nRemaining)
195 if (runLen < minRun) {
196 int force = nRemaining <= minRun ? nRemaining : minRun;
197 binarySort(a, lo, lo + force, lo + runLen, c);
198 runLen = force;
199 }
200
201 // Push run onto pending-run stack, and maybe merge
202 ts.pushRun(lo, runLen);
203 ts.mergeCollapse();
204
205 // Advance to find next run
206 lo += runLen;
207 nRemaining -= runLen;
208 } while (nRemaining != 0);
209
210 // Merge all remaining runs to complete sort
211 assert lo == hi;
212 ts.mergeForceCollapse();
213 assert ts.stackSize == 1;
214 }
215
216 /**
217 * Sorts the specified portion of the specified array using a binary
218 * insertion sort. This is the best method for sorting small numbers
219 * of elements. It requires O(n log n) compares, but O(n^2) data
220 * movement (worst case).
221 *
222 * If the initial part of the specified range is already sorted,
223 * this method can take advantage of it: the method assumes that the
224 * elements from index {@code lo}, inclusive, to {@code start},
225 * exclusive are already sorted.
226 *
227 * @param a the array in which a range is to be sorted
228 * @param lo the index of the first element in the range to be sorted
229 * @param hi the index after the last element in the range to be sorted
230 * @param start the index of the first element in the range that is
231 * not already known to be sorted (@code lo <= start <= hi}
232 * @param c comparator to used for the sort
233 */
234 @SuppressWarnings("fallthrough")
235 private static <T> void binarySort(T[] a, int lo, int hi, int start,
236 Comparator<? super T> c) {
237 assert lo <= start && start <= hi;
238 if (start == lo)
239 start++;
240 for ( ; start < hi; start++) {
241 T pivot = a[start];
242
243 // Set left (and right) to the index where a[start] (pivot) belongs
244 int left = lo;
245 int right = start;
246 assert left <= right;
247 /*
248 * Invariants:
249 * pivot >= all in [lo, left).
250 * pivot < all in [right, start).
251 */
252 while (left < right) {
253 int mid = (left + right) >>> 1;
254 if (c.compare(pivot, a[mid]) < 0)
255 right = mid;
256 else
257 left = mid + 1;
258 }
259 assert left == right;
260
261 /*
262 * The invariants still hold: pivot >= all in [lo, left) and
263 * pivot < all in [left, start), so pivot belongs at left. Note
264 * that if there are elements equal to pivot, left points to the
265 * first slot after them -- that's why this sort is stable.
266 * Slide elements over to make room to make room for pivot.
267 */
268 int n = start - left; // The number of elements to move
269 // Switch is just an optimization for arraycopy in default case
270 switch(n) {
271 case 2: a[left + 2] = a[left + 1];
272 case 1: a[left + 1] = a[left];
273 break;
274 default: System.arraycopy(a, left, a, left + 1, n);
275 }
276 a[left] = pivot;
277 }
278 }
279
280 /**
281 * Returns the length of the run beginning at the specified position in
282 * the specified array and reverses the run if it is descending (ensuring
283 * that the run will always be ascending when the method returns).
284 *
285 * A run is the longest ascending sequence with:
286 *
287 * a[lo] <= a[lo + 1] <= a[lo + 2] <= ...
288 *
289 * or the longest descending sequence with:
290 *
291 * a[lo] > a[lo + 1] > a[lo + 2] > ...
292 *
293 * For its intended use in a stable mergesort, the strictness of the
294 * definition of "descending" is needed so that the call can safely
295 * reverse a descending sequence without violating stability.
296 *
297 * @param a the array in which a run is to be counted and possibly reversed
298 * @param lo index of the first element in the run
299 * @param hi index after the last element that may be contained in the run.
300 It is required that @code{lo < hi}.
301 * @param c the comparator to used for the sort
302 * @return the length of the run beginning at the specified position in
303 * the specified array
304 */
305 private static <T> int countRunAndMakeAscending(T[] a, int lo, int hi,
306 Comparator<? super T> c) {
307 assert lo < hi;
308 int runHi = lo + 1;
309 if (runHi == hi)
310 return 1;
311
312 // Find end of run, and reverse range if descending
313 if (c.compare(a[runHi++], a[lo]) < 0) { // Descending
314 while(runHi < hi && c.compare(a[runHi], a[runHi - 1]) < 0)
315 runHi++;
316 reverseRange(a, lo, runHi);
317 } else { // Ascending
318 while (runHi < hi && c.compare(a[runHi], a[runHi - 1]) >= 0)
319 runHi++;
320 }
321
322 return runHi - lo;
323 }
324
325 /**
326 * Reverse the specified range of the specified array.
327 *
328 * @param a the array in which a range is to be reversed
329 * @param lo the index of the first element in the range to be reversed
330 * @param hi the index after the last element in the range to be reversed
331 */
332 private static void reverseRange(Object[] a, int lo, int hi) {
333 hi--;
334 while (lo < hi) {
335 Object t = a[lo];
336 a[lo++] = a[hi];
337 a[hi--] = t;
338 }
339 }
340
341 /**
342 * Returns the minimum acceptable run length for an array of the specified
343 * length. Natural runs shorter than this will be extended with
344 * {@link #binarySort}.
345 *
346 * Roughly speaking, the computation is:
347 *
348 * If n < MIN_MERGE, return n (it's too small to bother with fancy stuff).
349 * Else if n is an exact power of 2, return MIN_MERGE/2.
350 * Else return an int k, MIN_MERGE/2 <= k <= MIN_MERGE, such that n/k
351 * is close to, but strictly less than, an exact power of 2.
352 *
353 * For the rationale, see listsort.txt.
354 *
355 * @param n the length of the array to be sorted
356 * @return the length of the minimum run to be merged
357 */
358 private static int minRunLength(int n) {
359 assert n >= 0;
360 int r = 0; // Becomes 1 if any 1 bits are shifted off
361 while (n >= MIN_MERGE) {
362 r |= (n & 1);
363 n >>= 1;
364 }
365 return n + r;
366 }
367
368 /**
369 * Pushes the specified run onto the pending-run stack.
370 *
371 * @param runBase index of the first element in the run
372 * @param runLen the number of elements in the run
373 */
374 private void pushRun(int runBase, int runLen) {
375 this.runBase[stackSize] = runBase;
376 this.runLen[stackSize] = runLen;
377 stackSize++;
378 }
379
380 /**
381 * Examines the stack of runs waiting to be merged and merges adjacent runs
382 * until the stack invariants are reestablished:
383 *
384 * 1. runLen[i - 3] > runLen[i - 2] + runLen[i - 1]
385 * 2. runLen[i - 2] > runLen[i - 1]
386 *
387 * This method is called each time a new run is pushed onto the stack,
388 * so the invariants are guaranteed to hold for i < stackSize upon
389 * entry to the method.
390 */
391 private void mergeCollapse() {
392 while (stackSize > 1) {
393 int n = stackSize - 2;
394 if (n > 0 && runLen[n-1] <= runLen[n] + runLen[n+1]) {
395 if (runLen[n - 1] < runLen[n + 1])
396 n--;
397 mergeAt(n);
398 } else if (runLen[n] <= runLen[n + 1]) {
399 mergeAt(n);
400 } else {
401 break; // Invariant is established
402 }
403 }
404 }
405
406 /**
407 * Merges all runs on the stack until only one remains. This method is
408 * called once, to complete the sort.
409 */
410 private void mergeForceCollapse() {
411 while (stackSize > 1) {
412 int n = stackSize - 2;
413 if (n > 0 && runLen[n - 1] < runLen[n + 1])
414 n--;
415 mergeAt(n);
416 }
417 }
418
419 /**
420 * Merges the two runs at stack indices i and i+1. Run i must be
421 * the penultimate or antepenultimate run on the stack. In other words,
422 * i must be equal to stackSize-2 or stackSize-3.
423 *
424 * @param i stack index of the first of the two runs to merge
425 */
426 private void mergeAt(int i) {
427 assert stackSize >= 2;
428 assert i >= 0;
429 assert i == stackSize - 2 || i == stackSize - 3;
430
431 int base1 = runBase[i];
432 int len1 = runLen[i];
433 int base2 = runBase[i + 1];
434 int len2 = runLen[i + 1];
435 assert len1 > 0 && len2 > 0;
436 assert base1 + len1 == base2;
437
438 /*
439 * Record the length of the combined runs; if i is the 3rd-last
440 * run now, also slide over the last run (which isn't involved
441 * in this merge). The current run (i+1) goes away in any case.
442 */
443 runLen[i] = len1 + len2;
444 if (i == stackSize - 3) {
445 runBase[i + 1] = runBase[i + 2];
446 runLen[i + 1] = runLen[i + 2];
447 }
448 stackSize--;
449
450 /*
451 * Find where the first element of run2 goes in run1. Prior elements
452 * in run1 can be ignored (because they're already in place).
453 */
454 int k = gallopRight(a[base2], a, base1, len1, 0, c);
455 assert k >= 0;
456 base1 += k;
457 len1 -= k;
458 if (len1 == 0)
459 return;
460
461 /*
462 * Find where the last element of run1 goes in run2. Subsequent elements
463 * in run2 can be ignored (because they're already in place).
464 */
465 len2 = gallopLeft(a[base1 + len1 - 1], a, base2, len2, len2 - 1, c);
466 assert len2 >= 0;
467 if (len2 == 0)
468 return;
469
470 // Merge remaining runs, using tmp array with min(len1, len2) elements
471 if (len1 <= len2)
472 mergeLo(base1, len1, base2, len2);
473 else
474 mergeHi(base1, len1, base2, len2);
475 }
476
477 /**
478 * Locates the position at which to insert the specified key into the
479 * specified sorted range; if the range contains an element equal to key,
480 * returns the index of the leftmost equal element.
481 *
482 * @param key the key whose insertion point to search for
483 * @param a the array in which to search
484 * @param base the index of the first element in the range
485 * @param len the length of the range; must be > 0
486 * @param hint the index at which to begin the search, 0 <= hint < n.
487 * The closer hint is to the result, the faster this method will run.
488 * @param c the comparator used to order the range, and to search
489 * @return the int k, 0 <= k <= n such that a[b + k - 1] < key <= a[b + k],
490 * pretending that a[b - 1] is minus infinity and a[b + n] is infinity.
491 * In other words, key belongs at index b + k; or in other words,
492 * the first k elements of a should precede key, and the last n - k
493 * should follow it.
494 */
495 private static <T> int gallopLeft(T key, T[] a, int base, int len, int hint,
496 Comparator<? super T> c) {
497 assert len > 0 && hint >= 0 && hint < len;
498 int lastOfs = 0;
499 int ofs = 1;
500 if (c.compare(key, a[base + hint]) > 0) {
501 // Gallop right until a[base+hint+lastOfs] < key <= a[base+hint+ofs]
502 int maxOfs = len - hint;
503 while (ofs < maxOfs && c.compare(key, a[base + hint + ofs]) > 0) {
504 lastOfs = ofs;
505 ofs = (ofs << 1) + 1;
506 if (ofs <= 0) // int overflow
507 ofs = maxOfs;
508 }
509 if (ofs > maxOfs)
510 ofs = maxOfs;
511
512 // Make offsets relative to base
513 lastOfs += hint;
514 ofs += hint;
515 } else { // key <= a[base + hint]
516 // Gallop left until a[base+hint-ofs] < key <= a[base+hint-lastOfs]
517 final int maxOfs = hint + 1;
518 while (ofs < maxOfs && c.compare(key, a[base + hint - ofs]) <= 0) {
519 lastOfs = ofs;
520 ofs = (ofs << 1) + 1;
521 if (ofs <= 0) // int overflow
522 ofs = maxOfs;
523 }
524 if (ofs > maxOfs)
525 ofs = maxOfs;
526
527 // Make offsets relative to base
528 int tmp = lastOfs;
529 lastOfs = hint - ofs;
530 ofs = hint - tmp;
531 }
532 assert -1 <= lastOfs && lastOfs < ofs && ofs <= len;
533
534 /*
535 * Now a[base+lastOfs] < key <= a[base+ofs], so key belongs somewhere
536 * to the right of lastOfs but no farther right than ofs. Do a binary
537 * search, with invariant a[base + lastOfs - 1] < key <= a[base + ofs].
538 */
539 lastOfs++;
540 while (lastOfs < ofs) {
541 int m = lastOfs + ((ofs - lastOfs) >>> 1);
542
543 if (c.compare(key, a[base + m]) > 0)
544 lastOfs = m + 1; // a[base + m] < key
545 else
546 ofs = m; // key <= a[base + m]
547 }
548 assert lastOfs == ofs; // so a[base + ofs - 1] < key <= a[base + ofs]
549 return ofs;
550 }
551
552 /**
553 * Like gallopLeft, except that if the range contains an element equal to
554 * key, gallopRight returns the index after the rightmost equal element.
555 *
556 * @param key the key whose insertion point to search for
557 * @param a the array in which to search
558 * @param base the index of the first element in the range
559 * @param len the length of the range; must be > 0
560 * @param hint the index at which to begin the search, 0 <= hint < n.
561 * The closer hint is to the result, the faster this method will run.
562 * @param c the comparator used to order the range, and to search
563 * @return the int k, 0 <= k <= n such that a[b + k - 1] <= key < a[b + k]
564 */
565 private static <T> int gallopRight(T key, T[] a, int base, int len,
566 int hint, Comparator<? super T> c) {
567 assert len > 0 && hint >= 0 && hint < len;
568
569 int ofs = 1;
570 int lastOfs = 0;
571 if (c.compare(key, a[base + hint]) < 0) {
572 // Gallop left until a[b+hint - ofs] <= key < a[b+hint - lastOfs]
573 int maxOfs = hint + 1;
574 while (ofs < maxOfs && c.compare(key, a[base + hint - ofs]) < 0) {
575 lastOfs = ofs;
576 ofs = (ofs << 1) + 1;
577 if (ofs <= 0) // int overflow
578 ofs = maxOfs;
579 }
580 if (ofs > maxOfs)
581 ofs = maxOfs;
582
583 // Make offsets relative to b
584 int tmp = lastOfs;
585 lastOfs = hint - ofs;
586 ofs = hint - tmp;
587 } else { // a[b + hint] <= key
588 // Gallop right until a[b+hint + lastOfs] <= key < a[b+hint + ofs]
589 int maxOfs = len - hint;
590 while (ofs < maxOfs && c.compare(key, a[base + hint + ofs]) >= 0) {
591 lastOfs = ofs;
592 ofs = (ofs << 1) + 1;
593 if (ofs <= 0) // int overflow
594 ofs = maxOfs;
595 }
596 if (ofs > maxOfs)
597 ofs = maxOfs;
598
599 // Make offsets relative to b
600 lastOfs += hint;
601 ofs += hint;
602 }
603 assert -1 <= lastOfs && lastOfs < ofs && ofs <= len;
604
605 /*
606 * Now a[b + lastOfs] <= key < a[b + ofs], so key belongs somewhere to
607 * the right of lastOfs but no farther right than ofs. Do a binary
608 * search, with invariant a[b + lastOfs - 1] <= key < a[b + ofs].
609 */
610 lastOfs++;
611 while (lastOfs < ofs) {
612 int m = lastOfs + ((ofs - lastOfs) >>> 1);
613
614 if (c.compare(key, a[base + m]) < 0)
615 ofs = m; // key < a[b + m]
616 else
617 lastOfs = m + 1; // a[b + m] <= key
618 }
619 assert lastOfs == ofs; // so a[b + ofs - 1] <= key < a[b + ofs]
620 return ofs;
621 }
622
623 /**
624 * Merges two adjacent runs in place, in a stable fashion. The first
625 * element of the first run must be greater than the first element of the
626 * second run (a[base1] > a[base2]), and the last element of the first run
627 * (a[base1 + len1-1]) must be greater than all elements of the second run.
628 *
629 * For performance, this method should be called only when len1 <= len2;
630 * its twin, mergeHi should be called if len1 >= len2. (Either method
631 * may be called if len1 == len2.)
632 *
633 * @param base1 index of first element in first run to be merged
634 * @param len1 length of first run to be merged (must be > 0)
635 * @param base2 index of first element in second run to be merged
636 * (must be aBase + aLen)
637 * @param len2 length of second run to be merged (must be > 0)
638 */
639 private void mergeLo(int base1, int len1, int base2, int len2) {
640 assert len1 > 0 && len2 > 0 && base1 + len1 == base2;
641
642 // Copy first run into temp array
643 T[] a = this.a; // For performance
644 T[] tmp = ensureCapacity(len1);
645 System.arraycopy(a, base1, tmp, 0, len1);
646
647 int cursor1 = 0; // Indexes into tmp array
648 int cursor2 = base2; // Indexes int a
649 int dest = base1; // Indexes int a
650
651 // Move first element of second run and deal with degenerate cases
652 a[dest++] = a[cursor2++];
653 if (--len2 == 0) {
654 System.arraycopy(tmp, cursor1, a, dest, len1);
655 return;
656 }
657 if (len1 == 1) {
658 System.arraycopy(a, cursor2, a, dest, len2);
659 a[dest + len2] = tmp[cursor1]; // Last elt of run 1 to end of merge
660 return;
661 }
662
663 Comparator<? super T> c = this.c; // Use local variable for performance
664 int minGallop = this.minGallop; // " " " " "
665 outer:
666 while (true) {
667 int count1 = 0; // Number of times in a row that first run won
668 int count2 = 0; // Number of times in a row that second run won
669
670 /*
671 * Do the straightforward thing until (if ever) one run starts
672 * winning consistently.
673 */
674 do {
675 assert len1 > 1 && len2 > 0;
676 if (c.compare(a[cursor2], tmp[cursor1]) < 0) {
677 a[dest++] = a[cursor2++];
678 count2++;
679 count1 = 0;
680 if (--len2 == 0)
681 break outer;
682 } else {
683 a[dest++] = tmp[cursor1++];
684 count1++;
685 count2 = 0;
686 if (--len1 == 1)
687 break outer;
688 }
689 } while ((count1 | count2) < minGallop);
690
691 /*
692 * One run is winning so consistently that galloping may be a
693 * huge win. So try that, and continue galloping until (if ever)
694 * neither run appears to be winning consistently anymore.
695 */
696 do {
697 assert len1 > 1 && len2 > 0;
698 count1 = gallopRight(a[cursor2], tmp, cursor1, len1, 0, c);
699 if (count1 != 0) {
700 System.arraycopy(tmp, cursor1, a, dest, count1);
701 dest += count1;
702 cursor1 += count1;
703 len1 -= count1;
704 if (len1 <= 1) // len1 == 1 || len1 == 0
705 break outer;
706 }
707 a[dest++] = a[cursor2++];
708 if (--len2 == 0)
709 break outer;
710
711 count2 = gallopLeft(tmp[cursor1], a, cursor2, len2, 0, c);
712 if (count2 != 0) {
713 System.arraycopy(a, cursor2, a, dest, count2);
714 dest += count2;
715 cursor2 += count2;
716 len2 -= count2;
717 if (len2 == 0)
718 break outer;
719 }
720 a[dest++] = tmp[cursor1++];
721 if (--len1 == 1)
722 break outer;
723 minGallop--;
724 } while (count1 >= MIN_GALLOP | count2 >= MIN_GALLOP);
725 if (minGallop < 0)
726 minGallop = 0;
727 minGallop += 2; // Penalize for leaving gallop mode
728 } // End of "outer" loop
729 this.minGallop = minGallop < 1 ? 1 : minGallop; // Write back to field
730
731 if (len1 == 1) {
732 assert len2 > 0;
733 System.arraycopy(a, cursor2, a, dest, len2);
734 a[dest + len2] = tmp[cursor1]; // Last elt of run 1 to end of merge
735 } else if (len1 == 0) {
736 throw new IllegalArgumentException(
737 "Comparison method violates its general contract!");
738 } else {
739 assert len2 == 0;
740 assert len1 > 1;
741 System.arraycopy(tmp, cursor1, a, dest, len1);
742 }
743 }
744
745 /**
746 * Like mergeLo, except that this method should be called only if
747 * len1 >= len2; mergeLo should be called if len1 <= len2. (Either method
748 * may be called if len1 == len2.)
749 *
750 * @param base1 index of first element in first run to be merged
751 * @param len1 length of first run to be merged (must be > 0)
752 * @param base2 index of first element in second run to be merged
753 * (must be aBase + aLen)
754 * @param len2 length of second run to be merged (must be > 0)
755 */
756 private void mergeHi(int base1, int len1, int base2, int len2) {
757 assert len1 > 0 && len2 > 0 && base1 + len1 == base2;
758
759 // Copy second run into temp array
760 T[] a = this.a; // For performance
761 T[] tmp = ensureCapacity(len2);
762 System.arraycopy(a, base2, tmp, 0, len2);
763
764 int cursor1 = base1 + len1 - 1; // Indexes into a
765 int cursor2 = len2 - 1; // Indexes into tmp array
766 int dest = base2 + len2 - 1; // Indexes into a
767
768 // Move last element of first run and deal with degenerate cases
769 a[dest--] = a[cursor1--];
770 if (--len1 == 0) {
771 System.arraycopy(tmp, 0, a, dest - (len2 - 1), len2);
772 return;
773 }
774 if (len2 == 1) {
775 dest -= len1;
776 cursor1 -= len1;
777 System.arraycopy(a, cursor1 + 1, a, dest + 1, len1);
778 a[dest] = tmp[cursor2];
779 return;
780 }
781
782 Comparator<? super T> c = this.c; // Use local variable for performance
783 int minGallop = this.minGallop; // " " " " "
784 outer:
785 while (true) {
786 int count1 = 0; // Number of times in a row that first run won
787 int count2 = 0; // Number of times in a row that second run won
788
789 /*
790 * Do the straightforward thing until (if ever) one run
791 * appears to win consistently.
792 */
793 do {
794 assert len1 > 0 && len2 > 1;
795 if (c.compare(tmp[cursor2], a[cursor1]) < 0) {
796 a[dest--] = a[cursor1--];
797 count1++;
798 count2 = 0;
799 if (--len1 == 0)
800 break outer;
801 } else {
802 a[dest--] = tmp[cursor2--];
803 count2++;
804 count1 = 0;
805 if (--len2 == 1)
806 break outer;
807 }
808 } while ((count1 | count2) < minGallop);
809
810 /*
811 * One run is winning so consistently that galloping may be a
812 * huge win. So try that, and continue galloping until (if ever)
813 * neither run appears to be winning consistently anymore.
814 */
815 do {
816 assert len1 > 0 && len2 > 1;
817 count1 = len1 - gallopRight(tmp[cursor2], a, base1, len1, len1 - 1, c);
818 if (count1 != 0) {
819 dest -= count1;
820 cursor1 -= count1;
821 len1 -= count1;
822 System.arraycopy(a, cursor1 + 1, a, dest + 1, count1);
823 if (len1 == 0)
824 break outer;
825 }
826 a[dest--] = tmp[cursor2--];
827 if (--len2 == 1)
828 break outer;
829
830 count2 = len2 - gallopLeft(a[cursor1], tmp, 0, len2, len2 - 1, c);
831 if (count2 != 0) {
832 dest -= count2;
833 cursor2 -= count2;
834 len2 -= count2;
835 System.arraycopy(tmp, cursor2 + 1, a, dest + 1, count2);
836 if (len2 <= 1) // len2 == 1 || len2 == 0
837 break outer;
838 }
839 a[dest--] = a[cursor1--];
840 if (--len1 == 0)
841 break outer;
842 minGallop--;
843 } while (count1 >= MIN_GALLOP | count2 >= MIN_GALLOP);
844 if (minGallop < 0)
845 minGallop = 0;
846 minGallop += 2; // Penalize for leaving gallop mode
847 } // End of "outer" loop
848 this.minGallop = minGallop < 1 ? 1 : minGallop; // Write back to field
849
850 if (len2 == 1) {
851 assert len1 > 0;
852 dest -= len1;
853 cursor1 -= len1;
854 System.arraycopy(a, cursor1 + 1, a, dest + 1, len1);
855 a[dest] = tmp[cursor2]; // Move first elt of run2 to front of merge
856 } else if (len2 == 0) {
857 throw new IllegalArgumentException(
858 "Comparison method violates its general contract!");
859 } else {
860 assert len1 == 0;
861 assert len2 > 0;
862 System.arraycopy(tmp, 0, a, dest - (len2 - 1), len2);
863 }
864 }
865
866 /**
867 * Ensures that the external array tmp has at least the specified
868 * number of elements, increasing its size if necessary. The size
869 * increases exponentially to ensure amortized linear time complexity.
870 *
871 * @param minCapacity the minimum required capacity of the tmp array
872 * @return tmp, whether or not it grew
873 */
874 private T[] ensureCapacity(int minCapacity) {
875 if (tmp.length < minCapacity) {
876 // Compute smallest power of 2 > minCapacity
877 int newSize = minCapacity;
878 newSize |= newSize >> 1;
879 newSize |= newSize >> 2;
880 newSize |= newSize >> 4;
881 newSize |= newSize >> 8;
882 newSize |= newSize >> 16;
883 newSize++;
884
885 if (newSize < 0) // Not bloody likely!
886 newSize = minCapacity;
887 else
888 newSize = Math.min(newSize, a.length >>> 1);
889
890 @SuppressWarnings({"unchecked", "UnnecessaryLocalVariable"})
891 T[] newArray = (T[]) new Object[newSize];
892 tmp = newArray;
893 }
894 return tmp;
895 }
896
897 /**
898 * Checks that fromIndex and toIndex are in range, and throws an
899 * appropriate exception if they aren't.
900 *
901 * @param arrayLen the length of the array
902 * @param fromIndex the index of the first element of the range
903 * @param toIndex the index after the last element of the range
904 * @throws IllegalArgumentException if fromIndex > toIndex
905 * @throws ArrayIndexOutOfBoundsException if fromIndex < 0
906 * or toIndex > arrayLen
907 */
908 private static void rangeCheck(int arrayLen, int fromIndex, int toIndex) {
909 if (fromIndex > toIndex)
910 throw new IllegalArgumentException("fromIndex(" + fromIndex +
911 ") > toIndex(" + toIndex+")");
912 if (fromIndex < 0)
913 throw new ArrayIndexOutOfBoundsException(fromIndex);
914 if (toIndex > arrayLen)
915 throw new ArrayIndexOutOfBoundsException(toIndex);
916 }
917 }