Advertisement
Guest User

TimSort

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