Home » openjdk-7 » java » util » [javadoc | source]

    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   }

Home » openjdk-7 » java » util » [javadoc | source]