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