001/*
002 * Copyright (C) 2008 The Android Open Source Project
003 * 
004 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the
005 * License. You may obtain a copy of the License at
006 * 
007 * http://www.apache.org/licenses/LICENSE-2.0
008 * 
009 * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS"
010 * BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language
011 * governing permissions and limitations under the License.
012 */
013
014package squidpony.squidmath;
015
016import java.util.Comparator;
017
018/** A stable, adaptive, iterative mergesort that requires far fewer than n lg(n) comparisons when running on partially sorted
019 * arrays, while offering performance comparable to a traditional mergesort when run on random arrays. Like all proper mergesorts,
020 * this sort is stable and runs O(n log n) time (worst case). In the worst case, this sort requires temporary storage space for
021 * n/2 object references; in the best case, it requires only a small constant amount of space.
022 * <br>
023 * Most users won't ever need this class directly; its API is meant for implementors of ordered data structures like
024 * {@link OrderedMap} that allow sorting. In many cases those data structures expose methods like
025 * {@link OrderedSet#sort(Comparator)} or {@link OrderedMap#sortByValue(Comparator, int, int)}, and using those class'
026 * methods is a much better idea than trying to use TimSort directly on a data structure that already allows sorting.
027 * <br>
028 * This implementation was adapted from Tim Peters's list sort for Python, which is described in detail here:
029 * <br>
030 * http://svn.python.org/projects/python/trunk/Objects/listsort.txt
031 * <br>
032 * Tim's C code may be found here:
033 * <br>
034 * http://svn.python.org/projects/python/trunk/Objects/listobject.c
035 * <br>
036 * The underlying techniques are described in this paper (and may have even earlier origins):
037 * <br>
038 * "Optimistic Sorting and Information Theoretic Complexity" Peter McIlroy SODA (Fourth Annual ACM-SIAM Symposium on Discrete
039 * Algorithms), pp 467-474, Austin, Texas, 25-27 January 1993.
040 * <br>
041 * While the API to this class consists solely of static methods, it is (privately) instantiable; a TimSort instance holds the
042 * state of an ongoing sort, assuming the input array is large enough to warrant the full-blown TimSort. Small arrays are sorted
043 * in place, using a binary insertion sort.
044 */
045public class TimSort<T> {
046        /** This is the minimum sized sequence that will be merged. Shorter sequences will be lengthened by calling binarySort. If the
047         * entire array is less than this length, no merges will be performed.
048         * 
049         * This constant should be a power of two. It was 64 in Tim Peter's C implementation, but 32 was empirically determined to work
050         * better in this implementation. In the unlikely event that you set this constant to be a number that's not a power of two,
051         * you'll need to change the {@link #minRunLength} computation.
052         * 
053         * If you decrease this constant, you must change the stackLen computation in the TimSort constructor, or you risk an
054         * ArrayOutOfBounds exception. See listsort.txt for a discussion of the minimum stack length required as a function of the
055         * length of the array being sorted and the minimum merge sequence length. */
056        private static final int MIN_MERGE = 32;
057
058        /** The array being compared. */
059        private T[] a;
060
061        /** The ordering being modified. */
062        private IntVLA indices;
063
064        /** The comparator for this sort. */
065        private Comparator<? super T> c;
066
067        /** When we get into galloping mode, we stay there until both runs win less often than MIN_GALLOP consecutive times. */
068        private static final int MIN_GALLOP = 7;
069
070        /** This controls when we get *into* galloping mode. It is initialized to MIN_GALLOP. The mergeLo and mergeHi methods nudge it
071         * higher for random data, and lower for highly structured data. */
072        private int minGallop = MIN_GALLOP;
073
074        /** Maximum initial size of tmp array, which is used for merging. The array can grow to accommodate demand.
075         * 
076         * Unlike Tim's original C version, we do not allocate this much storage when sorting smaller arrays. This change was required
077         * for performance. */
078        private static final int INITIAL_TMP_STORAGE_LENGTH = 256;
079
080        /** Temp storage for merges. */
081        private int[] tmp; // Stores indices, like order
082        private int tmpCount;
083
084        /** A stack of pending runs yet to be merged. Run i starts at address base[i] and extends for len[i] elements. It's always true
085         * (so long as the indices are in bounds) that:
086         * 
087         * runBase[i] + runLen[i] == runBase[i + 1]
088         * 
089         * so we could cut the storage for this, but it's a minor amount, and keeping all the info explicit simplifies the code. */
090        private int stackSize; // Number of pending runs on stack
091        private final int[] runBase;
092        private final int[] runLen;
093
094        /** Asserts have been placed in if-statements for performance. To enable them, set this field to true and enable them in VM with
095         * a command line flag. If you modify this class, please do test the asserts! */
096        private static final boolean DEBUG = false;
097
098        TimSort () {
099                tmp = new int[INITIAL_TMP_STORAGE_LENGTH];
100                runBase = new int[40];
101                runLen = new int[40];
102        }
103
104        /** Creates a TimSort instance to maintain the state of an ongoing sort.
105         * 
106         * @param a the array to be sorted
107         * @param c the comparator to determine the order of the sort */
108        private TimSort (T[] a, IntVLA order, Comparator<? super T> c) {
109                this.a = a;
110                this.c = c;
111                this.indices = order;
112
113                // Allocate temp storage (which may be increased later if necessary)
114                int len = a.length;
115                tmp = new int[len < 2 * INITIAL_TMP_STORAGE_LENGTH ? len >>> 1 : INITIAL_TMP_STORAGE_LENGTH];
116                
117                /*
118                 * Allocate runs-to-be-merged stack (which cannot be expanded). The stack length requirements are described in listsort.txt.
119                 * The C version always uses the same stack length (85), but this was measured to be too expensive when sorting "mid-sized"
120                 * arrays (e.g., 100 elements) in Java. Therefore, we use smaller (but sufficiently large) stack lengths for smaller arrays.
121                 * The "magic numbers" in the computation below must be changed if MIN_MERGE is decreased. See the MIN_MERGE declaration
122                 * above for more information.
123                 */
124                int stackLen = (len < 120 ? 5 : len < 1542 ? 10 : len < 119151 ? 19 : 40);
125                runBase = new int[stackLen];
126                runLen = new int[stackLen];
127        }
128
129        /*
130         * The next two methods (which are public and static) constitute the entire API of this class.
131         */
132
133        /**
134         * Modifies {@code order} by comparing items in the array {@code a} with the Comparator {@code c}; not likely to be
135         * used externally except by code that extends or re-implements SquidLib data structures. Generally, {@code order}
136         * is the {@link OrderedMap#order} field or some similar IntVLA used to keep order in an OrderedSet or the like; it
137         * will be modified in-place, but the other parameters will be unchanged.
138         * @param a an array of T, where items will be compared using {@code c}; will not be modified
139         * @param order an IntVLA that stores indices in {@code a} in the order they would be iterated through; will be modified
140         * @param c a Comparator that can compare items in {@code a}
141         * @param <T> the type of items in {@code a} that {@code c} can compare
142         */
143        public static <T> void sort (T[] a, IntVLA order, Comparator<? super T> c) {
144                sort(a, order, 0, a.length, c);
145        }
146
147        /**
148         * Modifies {@code order} by comparing items from index {@code lo} inclusive to index {@code hi} exclusive in the
149         * array {@code a} with the Comparator {@code c}; not likely to be used externally except by code that extends or
150         * re-implements SquidLib data structures. Generally, {@code order} is the {@link OrderedMap#order} field or some
151         * similar IntVLA used to keep order in an OrderedSet or the like; it will be modified in-place, but the other
152         * parameters will be unchanged.
153         * @param a an array of T, where items will be compared using {@code c}; will not be modified
154         * @param order an IntVLA that stores indices in {@code a} in the order they would be iterated through; will be modified
155         * @param lo the inclusive start index to compare in {@code a} and change in {@code order}
156         * @param hi the exclusive end index to compare in {@code a} and change in {@code order}
157         * @param c a Comparator that can compare items in {@code a}
158         * @param <T> the type of items in {@code a} that {@code c} can compare
159         */
160        public static <T> void sort (T[] a, IntVLA order, int lo, int hi, Comparator<? super T> c) {
161                if (c == null) {
162                        return;
163                }
164
165                rangeCheck(a.length, lo, hi);
166                int nRemaining = hi - lo;
167                if (nRemaining < 2) return; // Arrays of size 0 and 1 are always sorted
168
169                // If array is small, do a "mini-TimSort" with no merges
170                if (nRemaining < MIN_MERGE) {
171                        int initRunLen = countRunAndMakeAscending(a, order, lo, hi, c);
172                        binarySort(a, order, lo, hi, lo + initRunLen, c);
173                        return;
174                }
175
176                /* March over the array once, left to right, finding natural runs, extending short natural runs to minRun elements, and
177                  merging runs to maintain stack invariant. */
178                TimSort<T> ts = new TimSort<>(a, order, c);
179                int minRun = minRunLength(nRemaining);
180                do {
181                        // Identify next run
182                        int runLen = countRunAndMakeAscending(a, order, lo, hi, c);
183
184                        // If run is short, extend to min(minRun, nRemaining)
185                        if (runLen < minRun) {
186                                int force = Math.min(nRemaining, minRun);
187                                binarySort(a, order, lo, lo + force, lo + runLen, c);
188                                runLen = force;
189                        }
190
191                        // Push run onto pending-run stack, and maybe merge
192                        ts.pushRun(lo, runLen);
193                        ts.mergeCollapse();
194
195                        // Advance to find next run
196                        lo += runLen;
197                        nRemaining -= runLen;
198                } while (nRemaining != 0);
199
200                // Merge all remaining runs to complete sort
201                if (DEBUG) assert lo == hi;
202                ts.mergeForceCollapse();
203                if (DEBUG) assert ts.stackSize == 1;
204        }
205
206        /** Sorts the specified portion of the specified array using a binary insertion sort. This is the best method for sorting small
207         * numbers of elements. It requires O(n log n) compares, but O(n^2) data movement (worst case).
208         * 
209         * If the initial part of the specified range is already sorted, this method can take advantage of it: the method assumes that
210         * the elements from index {@code lo}, inclusive, to {@code start}, exclusive are already sorted.
211         * 
212         * @param a the array in which a range is to be sorted
213         * @param lo the index of the first element in the range to be sorted
214         * @param hi the index after the last element in the range to be sorted
215         * @param start the index of the first element in the range that is not already known to be sorted (@code lo <= start <= hi}
216         * @param c comparator to used for the sort */
217        @SuppressWarnings("fallthrough")
218        private static <T> void binarySort (T[] a, IntVLA order, int lo, int hi, int start, Comparator<? super T> c) {
219                if (DEBUG) assert lo <= start && start <= hi;
220                if (start == lo) start++;
221                final int[] items = order.items;
222                for (; start < hi; start++) {
223                        int pivot = items[start];
224
225                        // Set left (and right) to the index where a[start] (pivot) belongs
226                        int left = lo;
227                        int right = start;
228                        if (DEBUG) assert left <= right;
229                        /*
230                         * Invariants: pivot >= all in [lo, left). pivot < all in [right, start).
231                         */
232                        while (left < right) {
233                                int mid = (left + right) >>> 1;
234                                if (c.compare(a[pivot], a[items[mid]]) < 0)
235                                        right = mid;
236                                else
237                                        left = mid + 1;
238                        }
239                        if (DEBUG) assert left == right;
240
241                        /*
242                         * The invariants still hold: pivot >= all in [lo, left) and pivot < all in [left, start), so pivot belongs at left. Note
243                         * that if there are elements equal to pivot, left points to the 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:
250                                items[left + 2] = items[left + 1];
251                        case 1:
252                                items[left + 1] = items[left];
253                                break;
254                        default:
255                                System.arraycopy(items, left, items, left + 1, n);
256                        }
257                        items[left] = pivot;
258                }
259        }
260
261        /** Returns the length of the run beginning at the specified position in the specified array and reverses the run if it is
262         * descending (ensuring that the run will always be ascending when the method returns).
263         * 
264         * A run is the longest ascending sequence with:
265         * 
266         * a[lo] <= a[lo + 1] <= a[lo + 2] <= ...
267         * 
268         * or the longest descending sequence with:
269         * 
270         * a[lo] > a[lo + 1] > a[lo + 2] > ...
271         * 
272         * For its intended use in a stable mergesort, the strictness of the definition of "descending" is needed so that the call can
273         * safely 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. It is required that @code{lo < hi}.
278         * @param c the comparator to used for the sort
279         * @return the length of the run beginning at the specified position in the specified array */
280        private static <T> int countRunAndMakeAscending (T[] a, IntVLA order, int lo, int hi, Comparator<? super T> c) {
281                if (DEBUG) assert lo < hi;
282                int runHi = lo + 1;
283                if (runHi == hi) return 1;
284                final int[] items = order.items;
285                // Find end of run, and reverse range if descending
286                if (c.compare(a[items[runHi++]], a[items[lo]]) < 0) { // Descending
287                        while (runHi < hi && c.compare(a[items[runHi]], a[items[runHi - 1]]) < 0)
288                                runHi++;
289                        reverseRange(items, lo, runHi);
290                } else { // Ascending
291                        while (runHi < hi && c.compare(a[items[runHi]], a[items[runHi - 1]]) >= 0)
292                                runHi++;
293                }
294
295                return runHi - lo;
296        }
297
298        /** Reverse the specified range of the specified array.
299         * 
300         * @param a the array in which a range is to be reversed
301         * @param lo the index of the first element in the range to be reversed
302         * @param hi the index after the last element in the range to be reversed */
303        private static void reverseRange (int[] a, int lo, int hi) {
304                hi--;
305                while (lo < hi) {
306                        int t = a[lo];
307                        a[lo++] = a[hi];
308                        a[hi--] = t;
309                }
310        }
311
312        /** Returns the minimum acceptable run length for an array of the specified length. Natural runs shorter than this will be
313         * extended with {@link #binarySort}.
314         * 
315         * Roughly speaking, the computation is:
316         * 
317         * If n < MIN_MERGE, return n (it's too small to bother with fancy stuff). Else if n is an exact power of 2, return
318         * MIN_MERGE/2. Else return an int k, MIN_MERGE/2 <= k <= MIN_MERGE, such that n/k is close to, but strictly less than, an
319         * exact power of 2.
320         * 
321         * For the rationale, see listsort.txt.
322         * 
323         * @param n the length of the array to be sorted
324         * @return the length of the minimum run to be merged */
325        private static int minRunLength (int n) {
326                if (DEBUG) assert n >= 0;
327                int r = 0; // Becomes 1 if any 1 bits are shifted off
328                while (n >= MIN_MERGE) {
329                        r |= (n & 1);
330                        n >>= 1;
331                }
332                return n + r;
333        }
334
335        /** Pushes the specified run onto the pending-run stack.
336         * 
337         * @param runBase index of the first element in the run
338         * @param runLen the number of elements in the run */
339        private void pushRun (int runBase, int runLen) {
340                this.runBase[stackSize] = runBase;
341                this.runLen[stackSize] = runLen;
342                stackSize++;
343        }
344
345        /** Examines the stack of runs waiting to be merged and merges adjacent runs until the stack invariants are reestablished:
346         * 
347         * 1. runLen[n - 2] > runLen[n - 1] + runLen[n] 2. runLen[n - 1] > runLen[n]
348         * 
349         * where n is the index of the last run in runLen.
350         * 
351         * This method has been formally verified to be correct after checking the last 4 runs.
352         * Checking for 3 runs results in an exception for large arrays.
353         * (Source: http://envisage-project.eu/proving-android-java-and-python-sorting-algorithm-is-broken-and-how-to-fix-it/)
354         * 
355         * This method is called each time a new run is pushed onto the stack, so the invariants are guaranteed to hold for i <
356         * stackSize upon entry to the method. */
357        private void mergeCollapse () {
358                while (stackSize > 1) {
359                        int n = stackSize - 2;
360                        if ((n >= 1 && runLen[n - 1] <= runLen[n] + runLen[n + 1]) || (n >= 2 && runLen[n - 2] <= runLen[n] + runLen[n - 1])) {
361                                if (runLen[n - 1] < runLen[n + 1]) n--;
362                        } else if (runLen[n] > runLen[n + 1]) {
363                                break; // Invariant is established
364                        }
365                        mergeAt(n);
366                }
367        }
368
369        /** Merges all runs on the stack until only one remains. This method is called once, to complete the sort. */
370        private void mergeForceCollapse () {
371                while (stackSize > 1) {
372                        int n = stackSize - 2;
373                        if (n > 0 && runLen[n - 1] < runLen[n + 1]) n--;
374                        mergeAt(n);
375                }
376        }
377
378        /** Merges the two runs at stack indices i and i+1. Run i must be the penultimate or antepenultimate run on the stack. In other
379         * words, i must be equal to stackSize-2 or stackSize-3.
380         * 
381         * @param i stack index of the first of the two runs to merge */
382        private void mergeAt (int i) {
383                if (DEBUG) assert stackSize >= 2;
384                if (DEBUG) assert i >= 0;
385                if (DEBUG) assert i == stackSize - 2 || i == stackSize - 3;
386
387                int base1 = runBase[i];
388                int len1 = runLen[i];
389                int base2 = runBase[i + 1];
390                int len2 = runLen[i + 1];
391                if (DEBUG) assert len1 > 0 && len2 > 0;
392                if (DEBUG) assert base1 + len1 == base2;
393
394                /*
395                 * Record the length of the combined runs; if i is the 3rd-last run now, also slide over the last run (which isn't involved
396                 * in this merge). The current run (i+1) goes away in any case.
397                 */
398                runLen[i] = len1 + len2;
399                if (i == stackSize - 3) {
400                        runBase[i + 1] = runBase[i + 2];
401                        runLen[i + 1] = runLen[i + 2];
402                }
403                stackSize--;
404
405                /*
406                 * Find where the first element of run2 goes in run1. Prior elements in run1 can be ignored (because they're already in
407                 * place).
408                 */
409                int k = gallopRight(a[indices.items[base2]], a, indices.items, base1, len1, 0, c);
410                if (DEBUG) assert k >= 0;
411                base1 += k;
412                len1 -= k;
413                if (len1 == 0) return;
414
415                /*
416                 * Find where the last element of run1 goes in run2. Subsequent elements in run2 can be ignored (because they're already in
417                 * place).
418                 */
419                len2 = gallopLeft(a[indices.items[base1 + len1 - 1]], a, indices.items, base2, len2, len2 - 1, c);
420                if (DEBUG) assert len2 >= 0;
421                if (len2 == 0) return;
422
423                // Merge remaining runs, using tmp array with min(len1, len2) elements
424                if (len1 <= len2)
425                        mergeLo(base1, len1, base2, len2);
426                else
427                        mergeHi(base1, len1, base2, len2);
428        }
429
430        /** Locates the position at which to insert the specified key into the specified sorted range; if the range contains an element
431         * equal to key, returns the index of the leftmost equal element.
432         * 
433         * @param key the key whose insertion point to search for
434         * @param a the array in which to search
435         * @param base the index of the first element in the range
436         * @param len the length of the range; must be > 0
437         * @param hint the index at which to begin the search, 0 <= hint < n. The closer hint is to the result, the faster this method
438         *           will run.
439         * @param c the comparator used to order the range, and to search
440         * @return the int k, 0 <= k <= n such that a[b + k - 1] < key <= a[b + k], pretending that a[b - 1] is minus infinity and a[b
441         *         + n] is infinity. In other words, key belongs at index b + k; or in other words, the first k elements of a should
442         *         precede key, and the last n - k should follow it. */
443        private static <T> int gallopLeft (T key, T[] a, int[] items, int base, int len, int hint, Comparator<? super T> c) {
444                if (DEBUG) assert hint >= 0 && hint < len;
445                int lastOfs = 0;
446                int ofs = 1;
447                if (c.compare(key, a[items[base + hint]]) > 0) {
448                        // Gallop right until a[base+hint+lastOfs] < key <= a[base+hint+ofs]
449                        int maxOfs = len - hint;
450                        while (ofs < maxOfs && c.compare(key, a[items[base + hint + ofs]]) > 0) {
451                                lastOfs = ofs;
452                                ofs = (ofs << 1) + 1;
453                                if (ofs <= 0) // int overflow
454                                        ofs = maxOfs;
455                        }
456                        if (ofs > maxOfs) ofs = maxOfs;
457
458                        // Make offsets relative to base
459                        lastOfs += hint;
460                        ofs += hint;
461                } else { // key <= a[base + hint]
462                        // Gallop left until a[base+hint-ofs] < key <= a[base+hint-lastOfs]
463                        final int maxOfs = hint + 1;
464                        while (ofs < maxOfs && c.compare(key, a[items[base + hint - ofs]]) <= 0) {
465                                lastOfs = ofs;
466                                ofs = (ofs << 1) + 1;
467                                if (ofs <= 0) // int overflow
468                                        ofs = maxOfs;
469                        }
470                        if (ofs > maxOfs) ofs = maxOfs;
471
472                        // Make offsets relative to base
473                        int tmp = lastOfs;
474                        lastOfs = hint - ofs;
475                        ofs = hint - tmp;
476                }
477                if (DEBUG) assert -1 <= lastOfs && lastOfs < ofs && ofs <= len;
478
479                /*
480                 * Now a[base+lastOfs] < key <= a[base+ofs], so key belongs somewhere to the right of lastOfs but no farther right than ofs.
481                 * Do a binary search, with invariant a[base + lastOfs - 1] < key <= a[base + ofs].
482                 */
483                lastOfs++;
484                while (lastOfs < ofs) {
485                        int m = lastOfs + ((ofs - lastOfs) >>> 1);
486
487                        if (c.compare(key, a[items[base + m]]) > 0)
488                                lastOfs = m + 1; // a[base + m] < key
489                        else
490                                ofs = m; // key <= a[base + m]
491                }
492                if (DEBUG) assert lastOfs == ofs; // so a[base + ofs - 1] < key <= a[base + ofs]
493                return ofs;
494        }
495
496        /** Like gallopLeft, except that if the range contains an element equal to key, gallopRight returns the index after the
497         * rightmost equal element.
498         * 
499         * @param key the key whose insertion point to search for
500         * @param a the array in which to search
501         * @param items the int array from inside the IntVLA to change the order in
502         * @param base the index of the first element in the range
503         * @param len the length of the range; must be > 0
504         * @param hint the index at which to begin the search, 0 <= hint < n. The closer hint is to the result, the faster this method
505         *           will run.
506         * @param c the comparator used to order the range, and to search
507         * @return the int k, 0 <= k <= n such that a[b + k - 1] <= key < a[b + k] */
508        private static <T> int gallopRight (T key, T[] a, int[] items, int base, int len, int hint, Comparator<? super T> c) {
509                if (DEBUG) assert hint >= 0 && hint < len;
510                int ofs = 1;
511                int lastOfs = 0;
512                if (c.compare(key, a[items[base + hint]]) < 0) {
513                        // Gallop left until a[b+hint - ofs] <= key < a[b+hint - lastOfs]
514                        int maxOfs = hint + 1;
515                        while (ofs < maxOfs && c.compare(key, a[items[base + hint - ofs]]) < 0) {
516                                lastOfs = ofs;
517                                ofs = (ofs << 1) + 1;
518                                if (ofs <= 0) // int overflow
519                                        ofs = maxOfs;
520                        }
521                        if (ofs > maxOfs) ofs = maxOfs;
522
523                        // Make offsets relative to b
524                        int tmp = lastOfs;
525                        lastOfs = hint - ofs;
526                        ofs = hint - tmp;
527                } else { // a[b + hint] <= key
528                        // Gallop right until a[b+hint + lastOfs] <= key < a[b+hint + ofs]
529                        int maxOfs = len - hint;
530                        while (ofs < maxOfs && c.compare(key, a[items[base + hint + ofs]]) >= 0) {
531                                lastOfs = ofs;
532                                ofs = (ofs << 1) + 1;
533                                if (ofs <= 0) // int overflow
534                                        ofs = maxOfs;
535                        }
536                        if (ofs > maxOfs) ofs = maxOfs;
537
538                        // Make offsets relative to b
539                        lastOfs += hint;
540                        ofs += hint;
541                }
542                if (DEBUG) assert -1 <= lastOfs && lastOfs < ofs && ofs <= len;
543
544                /*
545                 * Now a[b + lastOfs] <= key < a[b + ofs], so key belongs somewhere to the right of lastOfs but no farther right than ofs.
546                 * Do a binary search, with invariant a[b + lastOfs - 1] <= key < a[b + ofs].
547                 */
548                lastOfs++;
549                while (lastOfs < ofs) {
550                        int m = lastOfs + ((ofs - lastOfs) >>> 1);
551
552                        if (c.compare(key, a[items[base + m]]) < 0)
553                                ofs = m; // key < a[b + m]
554                        else
555                                lastOfs = m + 1; // a[b + m] <= key
556                }
557                if (DEBUG) assert lastOfs == ofs; // so a[b + ofs - 1] <= key < a[b + ofs]
558                return ofs;
559        }
560
561        /** Merges two adjacent runs in place, in a stable fashion. The first element of the first run must be greater than the first
562         * element of the second run (a[base1] > a[base2]), and the last element of the first run (a[base1 + len1-1]) must be greater
563         * than all elements of the second run.
564         * 
565         * For performance, this method should be called only when len1 <= len2; its twin, mergeHi should be called if len1 >= len2.
566         * (Either method may be called if len1 == len2.)
567         * 
568         * @param base1 index of first element in first run to be merged
569         * @param len1 length of first run to be merged (must be > 0)
570         * @param base2 index of first element in second run to be merged (must be aBase + aLen)
571         * @param len2 length of second run to be merged (must be > 0) */
572        private void mergeLo (int base1, int len1, int base2, int len2) {
573                if (DEBUG) assert len1 > 0 && len2 > 0 && base1 + len1 == base2;
574
575                // Copy first run into temp array
576                T[] a = this.a; // For performance
577                int[] items = indices.items;
578                int[] tmp = ensureCapacity(len1);
579                System.arraycopy(items, base1, tmp, 0, len1);
580
581                int cursor1 = 0; // Indexes into tmp array
582                int cursor2 = base2; // Indexes int a
583                int dest = base1; // Indexes int a
584
585                // Move first element of second run and deal with degenerate cases
586                items[dest++] = items[cursor2++];
587                if (--len2 == 0) {
588                        System.arraycopy(tmp, cursor1, items, dest, len1);
589                        return;
590                }
591                if (len1 == 1) {
592                        System.arraycopy(items, cursor2, items, dest, len2);
593                        items[dest + len2] = tmp[cursor1]; // Last elt of run 1 to end of merge
594                        return;
595                }
596
597                Comparator<? super T> c = this.c; // Use local variable for performance
598                int minGallop = this.minGallop;
599                outer:
600                while (true) {
601                        int count1 = 0; // Number of times in a row that first run won
602                        int count2 = 0; // Number of times in a row that second run won
603
604                        /*
605                         * Do the straightforward thing until (if ever) one run starts winning consistently.
606                         */
607                        do {
608                                if (DEBUG) assert len1 > 1 && len2 > 0;
609                                if (c.compare(a[items[cursor2]], a[tmp[cursor1]]) < 0) {
610                                        items[dest++] = items[cursor2++];
611                                        count2++;
612                                        count1 = 0;
613                                        if (--len2 == 0) break outer;
614                                } else {
615                                        items[dest++] = tmp[cursor1++];
616                                        count1++;
617                                        count2 = 0;
618                                        if (--len1 == 1) break outer;
619                                }
620                        } while ((count1 | count2) < minGallop);
621
622                        /*
623                         * One run is winning so consistently that galloping may be a huge win. So try that, and continue galloping until (if
624                         * ever) neither run appears to be winning consistently anymore.
625                         */
626                        do {
627                                if (DEBUG) assert len1 > 1 && len2 > 0;
628                                count1 = gallopRight(a[items[cursor2]], a, tmp, cursor1, len1, 0, c);
629                                if (count1 != 0) {
630                                        System.arraycopy(tmp, cursor1, items, dest, count1);
631                                        dest += count1;
632                                        cursor1 += count1;
633                                        len1 -= count1;
634                                        if (len1 <= 1) // len1 == 1 || len1 == 0
635                                                break outer;
636                                }
637                                items[dest++] = items[cursor2++];
638                                if (--len2 == 0) break outer;
639
640                                count2 = gallopLeft(a[tmp[cursor1]], a, items, cursor2, len2, 0, c);
641                                if (count2 != 0) {
642                                        System.arraycopy(items, cursor2, items, dest, count2);
643                                        dest += count2;
644                                        cursor2 += count2;
645                                        len2 -= count2;
646                                        if (len2 == 0) break outer;
647                                }
648                                items[dest++] = tmp[cursor1++];
649                                if (--len1 == 1) break outer;
650                                minGallop--;
651                        } while (count1 >= MIN_GALLOP | count2 >= MIN_GALLOP);
652                        if (minGallop < 0) minGallop = 0;
653                        minGallop += 2; // Penalize for leaving gallop mode
654                } // End of "outer" loop
655                this.minGallop = Math.max(minGallop, 1); // Write back to field
656
657                if (len1 == 1) {
658                        if (DEBUG) assert len2 > 0;
659                        System.arraycopy(items, cursor2, items, dest, len2);
660                        items[dest + len2] = tmp[cursor1]; // Last elt of run 1 to end of merge
661                } else if (len1 == 0) {
662                        throw new IllegalArgumentException("Comparison method violates its general contract!");
663                } else {
664                        if (DEBUG) assert len2 == 0;
665                        if (DEBUG) assert len1 > 1;
666                        System.arraycopy(tmp, cursor1, items, dest, len1);
667                }
668        }
669
670        /** Like mergeLo, except that this method should be called only if len1 >= len2; mergeLo should be called if len1 <= len2.
671         * (Either method may be called if len1 == len2.)
672         * 
673         * @param base1 index of first element in first run to be merged
674         * @param len1 length of first run to be merged (must be > 0)
675         * @param base2 index of first element in second run to be merged (must be aBase + aLen)
676         * @param len2 length of second run to be merged (must be > 0) */
677        private void mergeHi (int base1, int len1, int base2, int len2) {
678                if (DEBUG) assert len1 > 0 && len2 > 0 && base1 + len1 == base2;
679
680                // Copy second run into temp array
681                T[] a = this.a; // For performance
682                int[] items = indices.items;
683                int[] tmp = ensureCapacity(len2);
684                System.arraycopy(items, base2, tmp, 0, len2);
685
686                int cursor1 = base1 + len1 - 1; // Indexes into a
687                int cursor2 = len2 - 1; // Indexes into tmp array
688                int dest = base2 + len2 - 1; // Indexes into a
689
690                // Move last element of first run and deal with degenerate cases
691                items[dest--] = items[cursor1--];
692                if (--len1 == 0) {
693                        System.arraycopy(tmp, 0, items, dest - (len2 - 1), len2);
694                        return;
695                }
696                if (len2 == 1) {
697                        dest -= len1;
698                        cursor1 -= len1;
699                        System.arraycopy(items, cursor1 + 1, items, dest + 1, len1);
700                        items[dest] = tmp[cursor2];
701                        return;
702                }
703
704                Comparator<? super T> c = this.c; // Use local variable for performance
705                int minGallop = this.minGallop; // "    " "     " "
706                outer:
707                while (true) {
708                        int count1 = 0; // Number of times in a row that first run won
709                        int count2 = 0; // Number of times in a row that second run won
710
711                        /*
712                         * Do the straightforward thing until (if ever) one run appears to win consistently.
713                         */
714                        do {
715                                if (DEBUG) assert len1 > 0 && len2 > 1;
716                                if (c.compare(a[tmp[cursor2]], a[items[cursor1]]) < 0) {
717                                        items[dest--] = items[cursor1--];
718                                        count1++;
719                                        count2 = 0;
720                                        if (--len1 == 0) break outer;
721                                } else {
722                                        items[dest--] = tmp[cursor2--];
723                                        count2++;
724                                        count1 = 0;
725                                        if (--len2 == 1) break outer;
726                                }
727                        } while ((count1 | count2) < minGallop);
728
729                        /*
730                         * One run is winning so consistently that galloping may be a huge win. So try that, and continue galloping until (if
731                         * ever) neither run appears to be winning consistently anymore.
732                         */
733                        do {
734                                if (DEBUG) assert len1 > 0 && len2 > 1;
735                                count1 = len1 - gallopRight(a[tmp[cursor2]], a, items, base1, len1, len1 - 1, c);
736                                if (count1 != 0) {
737                                        dest -= count1;
738                                        cursor1 -= count1;
739                                        len1 -= count1;
740                                        System.arraycopy(items, cursor1 + 1, items, dest + 1, count1);
741                                        if (len1 == 0) break outer;
742                                }
743                                items[dest--] = tmp[cursor2--];
744                                if (--len2 == 1) break outer;
745
746                                count2 = len2 - gallopLeft(a[items[cursor1]], a, tmp, 0, len2, len2 - 1, c);
747                                if (count2 != 0) {
748                                        dest -= count2;
749                                        cursor2 -= count2;
750                                        len2 -= count2;
751                                        System.arraycopy(tmp, cursor2 + 1, items, dest + 1, count2);
752                                        if (len2 <= 1) // len2 == 1 || len2 == 0
753                                                break outer;
754                                }
755                                items[dest--] = items[cursor1--];
756                                if (--len1 == 0) break outer;
757                                minGallop--;
758                        } while (count1 >= MIN_GALLOP | count2 >= MIN_GALLOP);
759                        if (minGallop < 0) minGallop = 0;
760                        minGallop += 2; // Penalize for leaving gallop mode
761                } // End of "outer" loop
762                this.minGallop = Math.max(minGallop, 1); // Write back to field
763
764                if (len2 == 1) {
765                        if (DEBUG) assert len1 > 0;
766                        dest -= len1;
767                        cursor1 -= len1;
768                        System.arraycopy(items, cursor1 + 1, items, dest + 1, len1);
769                        items[dest] = tmp[cursor2]; // Move first elt of run2 to front of merge
770                } else if (len2 == 0) {
771                        throw new IllegalArgumentException("Comparison method violates its general contract!");
772                } else {
773                        if (DEBUG) assert len1 == 0;
774                        if (DEBUG) assert len2 > 0;
775                        System.arraycopy(tmp, 0, items, dest - (len2 - 1), len2);
776                }
777        }
778
779        /** Ensures that the external array tmp has at least the specified number of elements, increasing its size if necessary. The
780         * size increases exponentially to ensure amortized linear time complexity.
781         * 
782         * @param minCapacity the minimum required capacity of the tmp array
783         * @return tmp, whether or not it grew */
784        private int[] ensureCapacity (int minCapacity) {
785                tmpCount = Math.max(tmpCount, minCapacity);
786                if (tmp.length < minCapacity) {
787                        // Compute smallest power of 2 > minCapacity
788                        int newSize = minCapacity;
789                        newSize |= newSize >> 1;
790                        newSize |= newSize >> 2;
791                        newSize |= newSize >> 4;
792                        newSize |= newSize >> 8;
793                        newSize |= newSize >> 16;
794                        newSize++;
795
796                        if (newSize < 0) // Not bloody likely!
797                                newSize = minCapacity;
798                        else
799                                newSize = Math.min(newSize, a.length >>> 1);
800
801                        tmp = new int[newSize];
802                }
803                return tmp;
804        }
805
806        /** Checks that fromIndex and toIndex are in range, and throws an appropriate exception if they aren't.
807         * 
808         * @param arrayLen the length of the array
809         * @param fromIndex the index of the first element of the range
810         * @param toIndex the index after the last element of the range
811         * @throws IllegalArgumentException if fromIndex > toIndex
812         * @throws ArrayIndexOutOfBoundsException if fromIndex < 0 or toIndex > arrayLen */
813        private static void rangeCheck (int arrayLen, int fromIndex, int toIndex) {
814                if (fromIndex > toIndex) throw new IllegalArgumentException("fromIndex(" + fromIndex + ") > toIndex(" + toIndex + ")");
815                if (fromIndex < 0) throw new ArrayIndexOutOfBoundsException(fromIndex);
816                if (toIndex > arrayLen) throw new ArrayIndexOutOfBoundsException(toIndex);
817        }
818}