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