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