ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/main/java/util/ComparableTimSort.java
Revision: 1.3
Committed: Wed Sep 1 20:12:39 2010 UTC (13 years, 8 months ago) by jsr166
Branch: MAIN
Changes since 1.2: +2 -2 lines
Log Message:
coding style

File Contents

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