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