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