70 * ComparableTimSort, and DualPivotQuicksort sort methods that accept 71 * temp workspace array slices that we will have already allocated, so 72 * avoids redundant allocation. (Except for DualPivotQuicksort byte[] 73 * sort, that does not ever use a workspace array.) 74 */ 75 /*package*/ class ArraysParallelSortHelpers { 76 77 /* 78 * Style note: The task classes have a lot of parameters, that are 79 * stored as task fields and copied to local variables and used in 80 * compute() methods, We pack these into as few lines as possible, 81 * and hoist consistency checks among them before main loops, to 82 * reduce distraction. 83 */ 84 85 /** 86 * A placeholder task for Sorters, used for the lowest 87 * quartile task, that does not need to maintain array state. 88 */ 89 static final class EmptyCompleter extends CountedCompleter<Void> { 90 static final long serialVersionUID = 2446542900576103244L; 91 EmptyCompleter(CountedCompleter<?> p) { super(p); } 92 public final void compute() { } 93 } 94 95 /** 96 * A trigger for secondary merge of two merges 97 */ 98 static final class Relay extends CountedCompleter<Void> { 99 static final long serialVersionUID = 2446542900576103244L; 100 final CountedCompleter<?> task; 101 Relay(CountedCompleter<?> task) { 102 super(null, 1); 103 this.task = task; 104 } 105 public final void compute() { } 106 public final void onCompletion(CountedCompleter<?> t) { 107 task.compute(); 108 } 109 } 110 111 /** Object + Comparator support class */ 112 static final class FJObject { 113 static final class Sorter<T> extends CountedCompleter<Void> { 114 static final long serialVersionUID = 2446542900576103244L; 115 final T[] a, w; 116 final int base, size, wbase, gran; 117 Comparator<? super T> comparator; 118 Sorter(CountedCompleter<?> par, T[] a, T[] w, int base, int size, 119 int wbase, int gran, 120 Comparator<? super T> comparator) { 121 super(par); 122 this.a = a; this.w = w; this.base = base; this.size = size; 123 this.wbase = wbase; this.gran = gran; 124 this.comparator = comparator; 125 } 126 public final void compute() { 127 CountedCompleter<?> s = this; 128 Comparator<? super T> c = this.comparator; 129 T[] a = this.a, w = this.w; // localize all params 130 int b = this.base, n = this.size, wb = this.wbase, g = this.gran; 131 while (n > g) { 132 int h = n >>> 1, q = h >>> 1, u = h + q; // quartiles 133 Relay fc = new Relay(new Merger<>(s, w, a, wb, h, 134 wb+h, n-h, b, g, c)); 135 Relay rc = new Relay(new Merger<>(fc, a, w, b+h, q, 136 b+u, n-u, wb+h, g, c)); 137 new Sorter<>(rc, a, w, b+u, n-u, wb+u, g, c).fork(); 138 new Sorter<>(rc, a, w, b+h, q, wb+h, g, c).fork();; 139 Relay bc = new Relay(new Merger<>(fc, a, w, b, q, 140 b+q, h-q, wb, g, c)); 141 new Sorter<>(bc, a, w, b+q, h-q, wb+q, g, c).fork(); 142 s = new EmptyCompleter(bc); 143 n = q; 144 } 145 TimSort.sort(a, b, b + n, c, w, wb, n); 146 s.tryComplete(); 147 } 148 } 149 150 static final class Merger<T> extends CountedCompleter<Void> { 151 static final long serialVersionUID = 2446542900576103244L; 152 final T[] a, w; // main and workspace arrays 153 final int lbase, lsize, rbase, rsize, wbase, gran; 154 Comparator<? super T> comparator; 155 Merger(CountedCompleter<?> par, T[] a, T[] w, 156 int lbase, int lsize, int rbase, 157 int rsize, int wbase, int gran, 158 Comparator<? super T> comparator) { 159 super(par); 160 this.a = a; this.w = w; 161 this.lbase = lbase; this.lsize = lsize; 162 this.rbase = rbase; this.rsize = rsize; 163 this.wbase = wbase; this.gran = gran; 164 this.comparator = comparator; 165 } 166 167 public final void compute() { 168 Comparator<? super T> c = this.comparator; 169 T[] a = this.a, w = this.w; // localize all params 170 int lb = this.lbase, ln = this.lsize, rb = this.rbase, 216 } 217 else { 218 rb++; t = ar; 219 } 220 w[k++] = t; 221 } 222 if (rb < rf) 223 System.arraycopy(a, rb, w, k, rf - rb); 224 else if (lb < lf) 225 System.arraycopy(a, lb, w, k, lf - lb); 226 227 tryComplete(); 228 } 229 230 } 231 } // FJObject 232 233 /** byte support class */ 234 static final class FJByte { 235 static final class Sorter extends CountedCompleter<Void> { 236 static final long serialVersionUID = 2446542900576103244L; 237 final byte[] a, w; 238 final int base, size, wbase, gran; 239 Sorter(CountedCompleter<?> par, byte[] a, byte[] w, int base, 240 int size, int wbase, int gran) { 241 super(par); 242 this.a = a; this.w = w; this.base = base; this.size = size; 243 this.wbase = wbase; this.gran = gran; 244 } 245 public final void compute() { 246 CountedCompleter<?> s = this; 247 byte[] a = this.a, w = this.w; // localize all params 248 int b = this.base, n = this.size, wb = this.wbase, g = this.gran; 249 while (n > g) { 250 int h = n >>> 1, q = h >>> 1, u = h + q; // quartiles 251 Relay fc = new Relay(new Merger(s, w, a, wb, h, 252 wb+h, n-h, b, g)); 253 Relay rc = new Relay(new Merger(fc, a, w, b+h, q, 254 b+u, n-u, wb+h, g)); 255 new Sorter(rc, a, w, b+u, n-u, wb+u, g).fork(); 256 new Sorter(rc, a, w, b+h, q, wb+h, g).fork();; 257 Relay bc = new Relay(new Merger(fc, a, w, b, q, 258 b+q, h-q, wb, g)); 259 new Sorter(bc, a, w, b+q, h-q, wb+q, g).fork(); 260 s = new EmptyCompleter(bc); 261 n = q; 262 } 263 DualPivotQuicksort.sort(a, b, b + n - 1); 264 s.tryComplete(); 265 } 266 } 267 268 static final class Merger extends CountedCompleter<Void> { 269 static final long serialVersionUID = 2446542900576103244L; 270 final byte[] a, w; // main and workspace arrays 271 final int lbase, lsize, rbase, rsize, wbase, gran; 272 Merger(CountedCompleter<?> par, byte[] a, byte[] w, 273 int lbase, int lsize, int rbase, 274 int rsize, int wbase, int gran) { 275 super(par); 276 this.a = a; this.w = w; 277 this.lbase = lbase; this.lsize = lsize; 278 this.rbase = rbase; this.rsize = rsize; 279 this.wbase = wbase; this.gran = gran; 280 } 281 282 public final void compute() { 283 byte[] a = this.a, w = this.w; // localize all params 284 int lb = this.lbase, ln = this.lsize, rb = this.rbase, 285 rn = this.rsize, k = this.wbase, g = this.gran; 286 if (a == null || w == null || lb < 0 || rb < 0 || k < 0) 287 throw new IllegalStateException(); // hoist checks 288 for (int lh, rh;;) { // split larger, find point in smaller 327 if ((al = a[lb]) <= (ar = a[rb])) { 328 lb++; t = al; 329 } 330 else { 331 rb++; t = ar; 332 } 333 w[k++] = t; 334 } 335 if (rb < rf) 336 System.arraycopy(a, rb, w, k, rf - rb); 337 else if (lb < lf) 338 System.arraycopy(a, lb, w, k, lf - lb); 339 tryComplete(); 340 } 341 } 342 } // FJByte 343 344 /** char support class */ 345 static final class FJChar { 346 static final class Sorter extends CountedCompleter<Void> { 347 static final long serialVersionUID = 2446542900576103244L; 348 final char[] a, w; 349 final int base, size, wbase, gran; 350 Sorter(CountedCompleter<?> par, char[] a, char[] w, int base, 351 int size, int wbase, int gran) { 352 super(par); 353 this.a = a; this.w = w; this.base = base; this.size = size; 354 this.wbase = wbase; this.gran = gran; 355 } 356 public final void compute() { 357 CountedCompleter<?> s = this; 358 char[] a = this.a, w = this.w; // localize all params 359 int b = this.base, n = this.size, wb = this.wbase, g = this.gran; 360 while (n > g) { 361 int h = n >>> 1, q = h >>> 1, u = h + q; // quartiles 362 Relay fc = new Relay(new Merger(s, w, a, wb, h, 363 wb+h, n-h, b, g)); 364 Relay rc = new Relay(new Merger(fc, a, w, b+h, q, 365 b+u, n-u, wb+h, g)); 366 new Sorter(rc, a, w, b+u, n-u, wb+u, g).fork(); 367 new Sorter(rc, a, w, b+h, q, wb+h, g).fork();; 368 Relay bc = new Relay(new Merger(fc, a, w, b, q, 369 b+q, h-q, wb, g)); 370 new Sorter(bc, a, w, b+q, h-q, wb+q, g).fork(); 371 s = new EmptyCompleter(bc); 372 n = q; 373 } 374 DualPivotQuicksort.sort(a, b, b + n - 1, w, wb, n); 375 s.tryComplete(); 376 } 377 } 378 379 static final class Merger extends CountedCompleter<Void> { 380 static final long serialVersionUID = 2446542900576103244L; 381 final char[] a, w; // main and workspace arrays 382 final int lbase, lsize, rbase, rsize, wbase, gran; 383 Merger(CountedCompleter<?> par, char[] a, char[] w, 384 int lbase, int lsize, int rbase, 385 int rsize, int wbase, int gran) { 386 super(par); 387 this.a = a; this.w = w; 388 this.lbase = lbase; this.lsize = lsize; 389 this.rbase = rbase; this.rsize = rsize; 390 this.wbase = wbase; this.gran = gran; 391 } 392 393 public final void compute() { 394 char[] a = this.a, w = this.w; // localize all params 395 int lb = this.lbase, ln = this.lsize, rb = this.rbase, 396 rn = this.rsize, k = this.wbase, g = this.gran; 397 if (a == null || w == null || lb < 0 || rb < 0 || k < 0) 398 throw new IllegalStateException(); // hoist checks 399 for (int lh, rh;;) { // split larger, find point in smaller 438 if ((al = a[lb]) <= (ar = a[rb])) { 439 lb++; t = al; 440 } 441 else { 442 rb++; t = ar; 443 } 444 w[k++] = t; 445 } 446 if (rb < rf) 447 System.arraycopy(a, rb, w, k, rf - rb); 448 else if (lb < lf) 449 System.arraycopy(a, lb, w, k, lf - lb); 450 tryComplete(); 451 } 452 } 453 } // FJChar 454 455 /** short support class */ 456 static final class FJShort { 457 static final class Sorter extends CountedCompleter<Void> { 458 static final long serialVersionUID = 2446542900576103244L; 459 final short[] a, w; 460 final int base, size, wbase, gran; 461 Sorter(CountedCompleter<?> par, short[] a, short[] w, int base, 462 int size, int wbase, int gran) { 463 super(par); 464 this.a = a; this.w = w; this.base = base; this.size = size; 465 this.wbase = wbase; this.gran = gran; 466 } 467 public final void compute() { 468 CountedCompleter<?> s = this; 469 short[] a = this.a, w = this.w; // localize all params 470 int b = this.base, n = this.size, wb = this.wbase, g = this.gran; 471 while (n > g) { 472 int h = n >>> 1, q = h >>> 1, u = h + q; // quartiles 473 Relay fc = new Relay(new Merger(s, w, a, wb, h, 474 wb+h, n-h, b, g)); 475 Relay rc = new Relay(new Merger(fc, a, w, b+h, q, 476 b+u, n-u, wb+h, g)); 477 new Sorter(rc, a, w, b+u, n-u, wb+u, g).fork(); 478 new Sorter(rc, a, w, b+h, q, wb+h, g).fork();; 479 Relay bc = new Relay(new Merger(fc, a, w, b, q, 480 b+q, h-q, wb, g)); 481 new Sorter(bc, a, w, b+q, h-q, wb+q, g).fork(); 482 s = new EmptyCompleter(bc); 483 n = q; 484 } 485 DualPivotQuicksort.sort(a, b, b + n - 1, w, wb, n); 486 s.tryComplete(); 487 } 488 } 489 490 static final class Merger extends CountedCompleter<Void> { 491 static final long serialVersionUID = 2446542900576103244L; 492 final short[] a, w; // main and workspace arrays 493 final int lbase, lsize, rbase, rsize, wbase, gran; 494 Merger(CountedCompleter<?> par, short[] a, short[] w, 495 int lbase, int lsize, int rbase, 496 int rsize, int wbase, int gran) { 497 super(par); 498 this.a = a; this.w = w; 499 this.lbase = lbase; this.lsize = lsize; 500 this.rbase = rbase; this.rsize = rsize; 501 this.wbase = wbase; this.gran = gran; 502 } 503 504 public final void compute() { 505 short[] a = this.a, w = this.w; // localize all params 506 int lb = this.lbase, ln = this.lsize, rb = this.rbase, 507 rn = this.rsize, k = this.wbase, g = this.gran; 508 if (a == null || w == null || lb < 0 || rb < 0 || k < 0) 509 throw new IllegalStateException(); // hoist checks 510 for (int lh, rh;;) { // split larger, find point in smaller 549 if ((al = a[lb]) <= (ar = a[rb])) { 550 lb++; t = al; 551 } 552 else { 553 rb++; t = ar; 554 } 555 w[k++] = t; 556 } 557 if (rb < rf) 558 System.arraycopy(a, rb, w, k, rf - rb); 559 else if (lb < lf) 560 System.arraycopy(a, lb, w, k, lf - lb); 561 tryComplete(); 562 } 563 } 564 } // FJShort 565 566 /** int support class */ 567 static final class FJInt { 568 static final class Sorter extends CountedCompleter<Void> { 569 static final long serialVersionUID = 2446542900576103244L; 570 final int[] a, w; 571 final int base, size, wbase, gran; 572 Sorter(CountedCompleter<?> par, int[] a, int[] w, int base, 573 int size, int wbase, int gran) { 574 super(par); 575 this.a = a; this.w = w; this.base = base; this.size = size; 576 this.wbase = wbase; this.gran = gran; 577 } 578 public final void compute() { 579 CountedCompleter<?> s = this; 580 int[] a = this.a, w = this.w; // localize all params 581 int b = this.base, n = this.size, wb = this.wbase, g = this.gran; 582 while (n > g) { 583 int h = n >>> 1, q = h >>> 1, u = h + q; // quartiles 584 Relay fc = new Relay(new Merger(s, w, a, wb, h, 585 wb+h, n-h, b, g)); 586 Relay rc = new Relay(new Merger(fc, a, w, b+h, q, 587 b+u, n-u, wb+h, g)); 588 new Sorter(rc, a, w, b+u, n-u, wb+u, g).fork(); 589 new Sorter(rc, a, w, b+h, q, wb+h, g).fork();; 590 Relay bc = new Relay(new Merger(fc, a, w, b, q, 591 b+q, h-q, wb, g)); 592 new Sorter(bc, a, w, b+q, h-q, wb+q, g).fork(); 593 s = new EmptyCompleter(bc); 594 n = q; 595 } 596 DualPivotQuicksort.sort(a, b, b + n - 1, w, wb, n); 597 s.tryComplete(); 598 } 599 } 600 601 static final class Merger extends CountedCompleter<Void> { 602 static final long serialVersionUID = 2446542900576103244L; 603 final int[] a, w; // main and workspace arrays 604 final int lbase, lsize, rbase, rsize, wbase, gran; 605 Merger(CountedCompleter<?> par, int[] a, int[] w, 606 int lbase, int lsize, int rbase, 607 int rsize, int wbase, int gran) { 608 super(par); 609 this.a = a; this.w = w; 610 this.lbase = lbase; this.lsize = lsize; 611 this.rbase = rbase; this.rsize = rsize; 612 this.wbase = wbase; this.gran = gran; 613 } 614 615 public final void compute() { 616 int[] a = this.a, w = this.w; // localize all params 617 int lb = this.lbase, ln = this.lsize, rb = this.rbase, 618 rn = this.rsize, k = this.wbase, g = this.gran; 619 if (a == null || w == null || lb < 0 || rb < 0 || k < 0) 620 throw new IllegalStateException(); // hoist checks 621 for (int lh, rh;;) { // split larger, find point in smaller 660 if ((al = a[lb]) <= (ar = a[rb])) { 661 lb++; t = al; 662 } 663 else { 664 rb++; t = ar; 665 } 666 w[k++] = t; 667 } 668 if (rb < rf) 669 System.arraycopy(a, rb, w, k, rf - rb); 670 else if (lb < lf) 671 System.arraycopy(a, lb, w, k, lf - lb); 672 tryComplete(); 673 } 674 } 675 } // FJInt 676 677 /** long support class */ 678 static final class FJLong { 679 static final class Sorter extends CountedCompleter<Void> { 680 static final long serialVersionUID = 2446542900576103244L; 681 final long[] a, w; 682 final int base, size, wbase, gran; 683 Sorter(CountedCompleter<?> par, long[] a, long[] w, int base, 684 int size, int wbase, int gran) { 685 super(par); 686 this.a = a; this.w = w; this.base = base; this.size = size; 687 this.wbase = wbase; this.gran = gran; 688 } 689 public final void compute() { 690 CountedCompleter<?> s = this; 691 long[] a = this.a, w = this.w; // localize all params 692 int b = this.base, n = this.size, wb = this.wbase, g = this.gran; 693 while (n > g) { 694 int h = n >>> 1, q = h >>> 1, u = h + q; // quartiles 695 Relay fc = new Relay(new Merger(s, w, a, wb, h, 696 wb+h, n-h, b, g)); 697 Relay rc = new Relay(new Merger(fc, a, w, b+h, q, 698 b+u, n-u, wb+h, g)); 699 new Sorter(rc, a, w, b+u, n-u, wb+u, g).fork(); 700 new Sorter(rc, a, w, b+h, q, wb+h, g).fork();; 701 Relay bc = new Relay(new Merger(fc, a, w, b, q, 702 b+q, h-q, wb, g)); 703 new Sorter(bc, a, w, b+q, h-q, wb+q, g).fork(); 704 s = new EmptyCompleter(bc); 705 n = q; 706 } 707 DualPivotQuicksort.sort(a, b, b + n - 1, w, wb, n); 708 s.tryComplete(); 709 } 710 } 711 712 static final class Merger extends CountedCompleter<Void> { 713 static final long serialVersionUID = 2446542900576103244L; 714 final long[] a, w; // main and workspace arrays 715 final int lbase, lsize, rbase, rsize, wbase, gran; 716 Merger(CountedCompleter<?> par, long[] a, long[] w, 717 int lbase, int lsize, int rbase, 718 int rsize, int wbase, int gran) { 719 super(par); 720 this.a = a; this.w = w; 721 this.lbase = lbase; this.lsize = lsize; 722 this.rbase = rbase; this.rsize = rsize; 723 this.wbase = wbase; this.gran = gran; 724 } 725 726 public final void compute() { 727 long[] a = this.a, w = this.w; // localize all params 728 int lb = this.lbase, ln = this.lsize, rb = this.rbase, 729 rn = this.rsize, k = this.wbase, g = this.gran; 730 if (a == null || w == null || lb < 0 || rb < 0 || k < 0) 731 throw new IllegalStateException(); // hoist checks 732 for (int lh, rh;;) { // split larger, find point in smaller 771 if ((al = a[lb]) <= (ar = a[rb])) { 772 lb++; t = al; 773 } 774 else { 775 rb++; t = ar; 776 } 777 w[k++] = t; 778 } 779 if (rb < rf) 780 System.arraycopy(a, rb, w, k, rf - rb); 781 else if (lb < lf) 782 System.arraycopy(a, lb, w, k, lf - lb); 783 tryComplete(); 784 } 785 } 786 } // FJLong 787 788 /** float support class */ 789 static final class FJFloat { 790 static final class Sorter extends CountedCompleter<Void> { 791 static final long serialVersionUID = 2446542900576103244L; 792 final float[] a, w; 793 final int base, size, wbase, gran; 794 Sorter(CountedCompleter<?> par, float[] a, float[] w, int base, 795 int size, int wbase, int gran) { 796 super(par); 797 this.a = a; this.w = w; this.base = base; this.size = size; 798 this.wbase = wbase; this.gran = gran; 799 } 800 public final void compute() { 801 CountedCompleter<?> s = this; 802 float[] a = this.a, w = this.w; // localize all params 803 int b = this.base, n = this.size, wb = this.wbase, g = this.gran; 804 while (n > g) { 805 int h = n >>> 1, q = h >>> 1, u = h + q; // quartiles 806 Relay fc = new Relay(new Merger(s, w, a, wb, h, 807 wb+h, n-h, b, g)); 808 Relay rc = new Relay(new Merger(fc, a, w, b+h, q, 809 b+u, n-u, wb+h, g)); 810 new Sorter(rc, a, w, b+u, n-u, wb+u, g).fork(); 811 new Sorter(rc, a, w, b+h, q, wb+h, g).fork();; 812 Relay bc = new Relay(new Merger(fc, a, w, b, q, 813 b+q, h-q, wb, g)); 814 new Sorter(bc, a, w, b+q, h-q, wb+q, g).fork(); 815 s = new EmptyCompleter(bc); 816 n = q; 817 } 818 DualPivotQuicksort.sort(a, b, b + n - 1, w, wb, n); 819 s.tryComplete(); 820 } 821 } 822 823 static final class Merger extends CountedCompleter<Void> { 824 static final long serialVersionUID = 2446542900576103244L; 825 final float[] a, w; // main and workspace arrays 826 final int lbase, lsize, rbase, rsize, wbase, gran; 827 Merger(CountedCompleter<?> par, float[] a, float[] w, 828 int lbase, int lsize, int rbase, 829 int rsize, int wbase, int gran) { 830 super(par); 831 this.a = a; this.w = w; 832 this.lbase = lbase; this.lsize = lsize; 833 this.rbase = rbase; this.rsize = rsize; 834 this.wbase = wbase; this.gran = gran; 835 } 836 837 public final void compute() { 838 float[] a = this.a, w = this.w; // localize all params 839 int lb = this.lbase, ln = this.lsize, rb = this.rbase, 840 rn = this.rsize, k = this.wbase, g = this.gran; 841 if (a == null || w == null || lb < 0 || rb < 0 || k < 0) 842 throw new IllegalStateException(); // hoist checks 843 for (int lh, rh;;) { // split larger, find point in smaller 882 if ((al = a[lb]) <= (ar = a[rb])) { 883 lb++; t = al; 884 } 885 else { 886 rb++; t = ar; 887 } 888 w[k++] = t; 889 } 890 if (rb < rf) 891 System.arraycopy(a, rb, w, k, rf - rb); 892 else if (lb < lf) 893 System.arraycopy(a, lb, w, k, lf - lb); 894 tryComplete(); 895 } 896 } 897 } // FJFloat 898 899 /** double support class */ 900 static final class FJDouble { 901 static final class Sorter extends CountedCompleter<Void> { 902 static final long serialVersionUID = 2446542900576103244L; 903 final double[] a, w; 904 final int base, size, wbase, gran; 905 Sorter(CountedCompleter<?> par, double[] a, double[] w, int base, 906 int size, int wbase, int gran) { 907 super(par); 908 this.a = a; this.w = w; this.base = base; this.size = size; 909 this.wbase = wbase; this.gran = gran; 910 } 911 public final void compute() { 912 CountedCompleter<?> s = this; 913 double[] a = this.a, w = this.w; // localize all params 914 int b = this.base, n = this.size, wb = this.wbase, g = this.gran; 915 while (n > g) { 916 int h = n >>> 1, q = h >>> 1, u = h + q; // quartiles 917 Relay fc = new Relay(new Merger(s, w, a, wb, h, 918 wb+h, n-h, b, g)); 919 Relay rc = new Relay(new Merger(fc, a, w, b+h, q, 920 b+u, n-u, wb+h, g)); 921 new Sorter(rc, a, w, b+u, n-u, wb+u, g).fork(); 922 new Sorter(rc, a, w, b+h, q, wb+h, g).fork();; 923 Relay bc = new Relay(new Merger(fc, a, w, b, q, 924 b+q, h-q, wb, g)); 925 new Sorter(bc, a, w, b+q, h-q, wb+q, g).fork(); 926 s = new EmptyCompleter(bc); 927 n = q; 928 } 929 DualPivotQuicksort.sort(a, b, b + n - 1, w, wb, n); 930 s.tryComplete(); 931 } 932 } 933 934 static final class Merger extends CountedCompleter<Void> { 935 static final long serialVersionUID = 2446542900576103244L; 936 final double[] a, w; // main and workspace arrays 937 final int lbase, lsize, rbase, rsize, wbase, gran; 938 Merger(CountedCompleter<?> par, double[] a, double[] w, 939 int lbase, int lsize, int rbase, 940 int rsize, int wbase, int gran) { 941 super(par); 942 this.a = a; this.w = w; 943 this.lbase = lbase; this.lsize = lsize; 944 this.rbase = rbase; this.rsize = rsize; 945 this.wbase = wbase; this.gran = gran; 946 } 947 948 public final void compute() { 949 double[] a = this.a, w = this.w; // localize all params 950 int lb = this.lbase, ln = this.lsize, rb = this.rbase, 951 rn = this.rsize, k = this.wbase, g = this.gran; 952 if (a == null || w == null || lb < 0 || rb < 0 || k < 0) 953 throw new IllegalStateException(); // hoist checks 954 for (int lh, rh;;) { // split larger, find point in smaller | 70 * ComparableTimSort, and DualPivotQuicksort sort methods that accept 71 * temp workspace array slices that we will have already allocated, so 72 * avoids redundant allocation. (Except for DualPivotQuicksort byte[] 73 * sort, that does not ever use a workspace array.) 74 */ 75 /*package*/ class ArraysParallelSortHelpers { 76 77 /* 78 * Style note: The task classes have a lot of parameters, that are 79 * stored as task fields and copied to local variables and used in 80 * compute() methods, We pack these into as few lines as possible, 81 * and hoist consistency checks among them before main loops, to 82 * reduce distraction. 83 */ 84 85 /** 86 * A placeholder task for Sorters, used for the lowest 87 * quartile task, that does not need to maintain array state. 88 */ 89 static final class EmptyCompleter extends CountedCompleter<Void> { 90 @java.io.Serial 91 static final long serialVersionUID = 2446542900576103244L; 92 EmptyCompleter(CountedCompleter<?> p) { super(p); } 93 public final void compute() { } 94 } 95 96 /** 97 * A trigger for secondary merge of two merges 98 */ 99 static final class Relay extends CountedCompleter<Void> { 100 @java.io.Serial 101 static final long serialVersionUID = 2446542900576103244L; 102 final CountedCompleter<?> task; 103 Relay(CountedCompleter<?> task) { 104 super(null, 1); 105 this.task = task; 106 } 107 public final void compute() { } 108 public final void onCompletion(CountedCompleter<?> t) { 109 task.compute(); 110 } 111 } 112 113 /** Object + Comparator support class */ 114 static final class FJObject { 115 static final class Sorter<T> extends CountedCompleter<Void> { 116 @java.io.Serial 117 static final long serialVersionUID = 2446542900576103244L; 118 final T[] a, w; 119 final int base, size, wbase, gran; 120 Comparator<? super T> comparator; 121 Sorter(CountedCompleter<?> par, T[] a, T[] w, int base, int size, 122 int wbase, int gran, 123 Comparator<? super T> comparator) { 124 super(par); 125 this.a = a; this.w = w; this.base = base; this.size = size; 126 this.wbase = wbase; this.gran = gran; 127 this.comparator = comparator; 128 } 129 public final void compute() { 130 CountedCompleter<?> s = this; 131 Comparator<? super T> c = this.comparator; 132 T[] a = this.a, w = this.w; // localize all params 133 int b = this.base, n = this.size, wb = this.wbase, g = this.gran; 134 while (n > g) { 135 int h = n >>> 1, q = h >>> 1, u = h + q; // quartiles 136 Relay fc = new Relay(new Merger<>(s, w, a, wb, h, 137 wb+h, n-h, b, g, c)); 138 Relay rc = new Relay(new Merger<>(fc, a, w, b+h, q, 139 b+u, n-u, wb+h, g, c)); 140 new Sorter<>(rc, a, w, b+u, n-u, wb+u, g, c).fork(); 141 new Sorter<>(rc, a, w, b+h, q, wb+h, g, c).fork();; 142 Relay bc = new Relay(new Merger<>(fc, a, w, b, q, 143 b+q, h-q, wb, g, c)); 144 new Sorter<>(bc, a, w, b+q, h-q, wb+q, g, c).fork(); 145 s = new EmptyCompleter(bc); 146 n = q; 147 } 148 TimSort.sort(a, b, b + n, c, w, wb, n); 149 s.tryComplete(); 150 } 151 } 152 153 static final class Merger<T> extends CountedCompleter<Void> { 154 @java.io.Serial 155 static final long serialVersionUID = 2446542900576103244L; 156 final T[] a, w; // main and workspace arrays 157 final int lbase, lsize, rbase, rsize, wbase, gran; 158 Comparator<? super T> comparator; 159 Merger(CountedCompleter<?> par, T[] a, T[] w, 160 int lbase, int lsize, int rbase, 161 int rsize, int wbase, int gran, 162 Comparator<? super T> comparator) { 163 super(par); 164 this.a = a; this.w = w; 165 this.lbase = lbase; this.lsize = lsize; 166 this.rbase = rbase; this.rsize = rsize; 167 this.wbase = wbase; this.gran = gran; 168 this.comparator = comparator; 169 } 170 171 public final void compute() { 172 Comparator<? super T> c = this.comparator; 173 T[] a = this.a, w = this.w; // localize all params 174 int lb = this.lbase, ln = this.lsize, rb = this.rbase, 220 } 221 else { 222 rb++; t = ar; 223 } 224 w[k++] = t; 225 } 226 if (rb < rf) 227 System.arraycopy(a, rb, w, k, rf - rb); 228 else if (lb < lf) 229 System.arraycopy(a, lb, w, k, lf - lb); 230 231 tryComplete(); 232 } 233 234 } 235 } // FJObject 236 237 /** byte support class */ 238 static final class FJByte { 239 static final class Sorter extends CountedCompleter<Void> { 240 @java.io.Serial 241 static final long serialVersionUID = 2446542900576103244L; 242 final byte[] a, w; 243 final int base, size, wbase, gran; 244 Sorter(CountedCompleter<?> par, byte[] a, byte[] w, int base, 245 int size, int wbase, int gran) { 246 super(par); 247 this.a = a; this.w = w; this.base = base; this.size = size; 248 this.wbase = wbase; this.gran = gran; 249 } 250 public final void compute() { 251 CountedCompleter<?> s = this; 252 byte[] a = this.a, w = this.w; // localize all params 253 int b = this.base, n = this.size, wb = this.wbase, g = this.gran; 254 while (n > g) { 255 int h = n >>> 1, q = h >>> 1, u = h + q; // quartiles 256 Relay fc = new Relay(new Merger(s, w, a, wb, h, 257 wb+h, n-h, b, g)); 258 Relay rc = new Relay(new Merger(fc, a, w, b+h, q, 259 b+u, n-u, wb+h, g)); 260 new Sorter(rc, a, w, b+u, n-u, wb+u, g).fork(); 261 new Sorter(rc, a, w, b+h, q, wb+h, g).fork();; 262 Relay bc = new Relay(new Merger(fc, a, w, b, q, 263 b+q, h-q, wb, g)); 264 new Sorter(bc, a, w, b+q, h-q, wb+q, g).fork(); 265 s = new EmptyCompleter(bc); 266 n = q; 267 } 268 DualPivotQuicksort.sort(a, b, b + n - 1); 269 s.tryComplete(); 270 } 271 } 272 273 static final class Merger extends CountedCompleter<Void> { 274 @java.io.Serial 275 static final long serialVersionUID = 2446542900576103244L; 276 final byte[] a, w; // main and workspace arrays 277 final int lbase, lsize, rbase, rsize, wbase, gran; 278 Merger(CountedCompleter<?> par, byte[] a, byte[] w, 279 int lbase, int lsize, int rbase, 280 int rsize, int wbase, int gran) { 281 super(par); 282 this.a = a; this.w = w; 283 this.lbase = lbase; this.lsize = lsize; 284 this.rbase = rbase; this.rsize = rsize; 285 this.wbase = wbase; this.gran = gran; 286 } 287 288 public final void compute() { 289 byte[] a = this.a, w = this.w; // localize all params 290 int lb = this.lbase, ln = this.lsize, rb = this.rbase, 291 rn = this.rsize, k = this.wbase, g = this.gran; 292 if (a == null || w == null || lb < 0 || rb < 0 || k < 0) 293 throw new IllegalStateException(); // hoist checks 294 for (int lh, rh;;) { // split larger, find point in smaller 333 if ((al = a[lb]) <= (ar = a[rb])) { 334 lb++; t = al; 335 } 336 else { 337 rb++; t = ar; 338 } 339 w[k++] = t; 340 } 341 if (rb < rf) 342 System.arraycopy(a, rb, w, k, rf - rb); 343 else if (lb < lf) 344 System.arraycopy(a, lb, w, k, lf - lb); 345 tryComplete(); 346 } 347 } 348 } // FJByte 349 350 /** char support class */ 351 static final class FJChar { 352 static final class Sorter extends CountedCompleter<Void> { 353 @java.io.Serial 354 static final long serialVersionUID = 2446542900576103244L; 355 final char[] a, w; 356 final int base, size, wbase, gran; 357 Sorter(CountedCompleter<?> par, char[] a, char[] w, int base, 358 int size, int wbase, int gran) { 359 super(par); 360 this.a = a; this.w = w; this.base = base; this.size = size; 361 this.wbase = wbase; this.gran = gran; 362 } 363 public final void compute() { 364 CountedCompleter<?> s = this; 365 char[] a = this.a, w = this.w; // localize all params 366 int b = this.base, n = this.size, wb = this.wbase, g = this.gran; 367 while (n > g) { 368 int h = n >>> 1, q = h >>> 1, u = h + q; // quartiles 369 Relay fc = new Relay(new Merger(s, w, a, wb, h, 370 wb+h, n-h, b, g)); 371 Relay rc = new Relay(new Merger(fc, a, w, b+h, q, 372 b+u, n-u, wb+h, g)); 373 new Sorter(rc, a, w, b+u, n-u, wb+u, g).fork(); 374 new Sorter(rc, a, w, b+h, q, wb+h, g).fork();; 375 Relay bc = new Relay(new Merger(fc, a, w, b, q, 376 b+q, h-q, wb, g)); 377 new Sorter(bc, a, w, b+q, h-q, wb+q, g).fork(); 378 s = new EmptyCompleter(bc); 379 n = q; 380 } 381 DualPivotQuicksort.sort(a, b, b + n - 1, w, wb, n); 382 s.tryComplete(); 383 } 384 } 385 386 static final class Merger extends CountedCompleter<Void> { 387 @java.io.Serial 388 static final long serialVersionUID = 2446542900576103244L; 389 final char[] a, w; // main and workspace arrays 390 final int lbase, lsize, rbase, rsize, wbase, gran; 391 Merger(CountedCompleter<?> par, char[] a, char[] w, 392 int lbase, int lsize, int rbase, 393 int rsize, int wbase, int gran) { 394 super(par); 395 this.a = a; this.w = w; 396 this.lbase = lbase; this.lsize = lsize; 397 this.rbase = rbase; this.rsize = rsize; 398 this.wbase = wbase; this.gran = gran; 399 } 400 401 public final void compute() { 402 char[] a = this.a, w = this.w; // localize all params 403 int lb = this.lbase, ln = this.lsize, rb = this.rbase, 404 rn = this.rsize, k = this.wbase, g = this.gran; 405 if (a == null || w == null || lb < 0 || rb < 0 || k < 0) 406 throw new IllegalStateException(); // hoist checks 407 for (int lh, rh;;) { // split larger, find point in smaller 446 if ((al = a[lb]) <= (ar = a[rb])) { 447 lb++; t = al; 448 } 449 else { 450 rb++; t = ar; 451 } 452 w[k++] = t; 453 } 454 if (rb < rf) 455 System.arraycopy(a, rb, w, k, rf - rb); 456 else if (lb < lf) 457 System.arraycopy(a, lb, w, k, lf - lb); 458 tryComplete(); 459 } 460 } 461 } // FJChar 462 463 /** short support class */ 464 static final class FJShort { 465 static final class Sorter extends CountedCompleter<Void> { 466 @java.io.Serial 467 static final long serialVersionUID = 2446542900576103244L; 468 final short[] a, w; 469 final int base, size, wbase, gran; 470 Sorter(CountedCompleter<?> par, short[] a, short[] w, int base, 471 int size, int wbase, int gran) { 472 super(par); 473 this.a = a; this.w = w; this.base = base; this.size = size; 474 this.wbase = wbase; this.gran = gran; 475 } 476 public final void compute() { 477 CountedCompleter<?> s = this; 478 short[] a = this.a, w = this.w; // localize all params 479 int b = this.base, n = this.size, wb = this.wbase, g = this.gran; 480 while (n > g) { 481 int h = n >>> 1, q = h >>> 1, u = h + q; // quartiles 482 Relay fc = new Relay(new Merger(s, w, a, wb, h, 483 wb+h, n-h, b, g)); 484 Relay rc = new Relay(new Merger(fc, a, w, b+h, q, 485 b+u, n-u, wb+h, g)); 486 new Sorter(rc, a, w, b+u, n-u, wb+u, g).fork(); 487 new Sorter(rc, a, w, b+h, q, wb+h, g).fork();; 488 Relay bc = new Relay(new Merger(fc, a, w, b, q, 489 b+q, h-q, wb, g)); 490 new Sorter(bc, a, w, b+q, h-q, wb+q, g).fork(); 491 s = new EmptyCompleter(bc); 492 n = q; 493 } 494 DualPivotQuicksort.sort(a, b, b + n - 1, w, wb, n); 495 s.tryComplete(); 496 } 497 } 498 499 static final class Merger extends CountedCompleter<Void> { 500 @java.io.Serial 501 static final long serialVersionUID = 2446542900576103244L; 502 final short[] a, w; // main and workspace arrays 503 final int lbase, lsize, rbase, rsize, wbase, gran; 504 Merger(CountedCompleter<?> par, short[] a, short[] w, 505 int lbase, int lsize, int rbase, 506 int rsize, int wbase, int gran) { 507 super(par); 508 this.a = a; this.w = w; 509 this.lbase = lbase; this.lsize = lsize; 510 this.rbase = rbase; this.rsize = rsize; 511 this.wbase = wbase; this.gran = gran; 512 } 513 514 public final void compute() { 515 short[] a = this.a, w = this.w; // localize all params 516 int lb = this.lbase, ln = this.lsize, rb = this.rbase, 517 rn = this.rsize, k = this.wbase, g = this.gran; 518 if (a == null || w == null || lb < 0 || rb < 0 || k < 0) 519 throw new IllegalStateException(); // hoist checks 520 for (int lh, rh;;) { // split larger, find point in smaller 559 if ((al = a[lb]) <= (ar = a[rb])) { 560 lb++; t = al; 561 } 562 else { 563 rb++; t = ar; 564 } 565 w[k++] = t; 566 } 567 if (rb < rf) 568 System.arraycopy(a, rb, w, k, rf - rb); 569 else if (lb < lf) 570 System.arraycopy(a, lb, w, k, lf - lb); 571 tryComplete(); 572 } 573 } 574 } // FJShort 575 576 /** int support class */ 577 static final class FJInt { 578 static final class Sorter extends CountedCompleter<Void> { 579 @java.io.Serial 580 static final long serialVersionUID = 2446542900576103244L; 581 final int[] a, w; 582 final int base, size, wbase, gran; 583 Sorter(CountedCompleter<?> par, int[] a, int[] w, int base, 584 int size, int wbase, int gran) { 585 super(par); 586 this.a = a; this.w = w; this.base = base; this.size = size; 587 this.wbase = wbase; this.gran = gran; 588 } 589 public final void compute() { 590 CountedCompleter<?> s = this; 591 int[] a = this.a, w = this.w; // localize all params 592 int b = this.base, n = this.size, wb = this.wbase, g = this.gran; 593 while (n > g) { 594 int h = n >>> 1, q = h >>> 1, u = h + q; // quartiles 595 Relay fc = new Relay(new Merger(s, w, a, wb, h, 596 wb+h, n-h, b, g)); 597 Relay rc = new Relay(new Merger(fc, a, w, b+h, q, 598 b+u, n-u, wb+h, g)); 599 new Sorter(rc, a, w, b+u, n-u, wb+u, g).fork(); 600 new Sorter(rc, a, w, b+h, q, wb+h, g).fork();; 601 Relay bc = new Relay(new Merger(fc, a, w, b, q, 602 b+q, h-q, wb, g)); 603 new Sorter(bc, a, w, b+q, h-q, wb+q, g).fork(); 604 s = new EmptyCompleter(bc); 605 n = q; 606 } 607 DualPivotQuicksort.sort(a, b, b + n - 1, w, wb, n); 608 s.tryComplete(); 609 } 610 } 611 612 static final class Merger extends CountedCompleter<Void> { 613 @java.io.Serial 614 static final long serialVersionUID = 2446542900576103244L; 615 final int[] a, w; // main and workspace arrays 616 final int lbase, lsize, rbase, rsize, wbase, gran; 617 Merger(CountedCompleter<?> par, int[] a, int[] w, 618 int lbase, int lsize, int rbase, 619 int rsize, int wbase, int gran) { 620 super(par); 621 this.a = a; this.w = w; 622 this.lbase = lbase; this.lsize = lsize; 623 this.rbase = rbase; this.rsize = rsize; 624 this.wbase = wbase; this.gran = gran; 625 } 626 627 public final void compute() { 628 int[] a = this.a, w = this.w; // localize all params 629 int lb = this.lbase, ln = this.lsize, rb = this.rbase, 630 rn = this.rsize, k = this.wbase, g = this.gran; 631 if (a == null || w == null || lb < 0 || rb < 0 || k < 0) 632 throw new IllegalStateException(); // hoist checks 633 for (int lh, rh;;) { // split larger, find point in smaller 672 if ((al = a[lb]) <= (ar = a[rb])) { 673 lb++; t = al; 674 } 675 else { 676 rb++; t = ar; 677 } 678 w[k++] = t; 679 } 680 if (rb < rf) 681 System.arraycopy(a, rb, w, k, rf - rb); 682 else if (lb < lf) 683 System.arraycopy(a, lb, w, k, lf - lb); 684 tryComplete(); 685 } 686 } 687 } // FJInt 688 689 /** long support class */ 690 static final class FJLong { 691 static final class Sorter extends CountedCompleter<Void> { 692 @java.io.Serial 693 static final long serialVersionUID = 2446542900576103244L; 694 final long[] a, w; 695 final int base, size, wbase, gran; 696 Sorter(CountedCompleter<?> par, long[] a, long[] w, int base, 697 int size, int wbase, int gran) { 698 super(par); 699 this.a = a; this.w = w; this.base = base; this.size = size; 700 this.wbase = wbase; this.gran = gran; 701 } 702 public final void compute() { 703 CountedCompleter<?> s = this; 704 long[] a = this.a, w = this.w; // localize all params 705 int b = this.base, n = this.size, wb = this.wbase, g = this.gran; 706 while (n > g) { 707 int h = n >>> 1, q = h >>> 1, u = h + q; // quartiles 708 Relay fc = new Relay(new Merger(s, w, a, wb, h, 709 wb+h, n-h, b, g)); 710 Relay rc = new Relay(new Merger(fc, a, w, b+h, q, 711 b+u, n-u, wb+h, g)); 712 new Sorter(rc, a, w, b+u, n-u, wb+u, g).fork(); 713 new Sorter(rc, a, w, b+h, q, wb+h, g).fork();; 714 Relay bc = new Relay(new Merger(fc, a, w, b, q, 715 b+q, h-q, wb, g)); 716 new Sorter(bc, a, w, b+q, h-q, wb+q, g).fork(); 717 s = new EmptyCompleter(bc); 718 n = q; 719 } 720 DualPivotQuicksort.sort(a, b, b + n - 1, w, wb, n); 721 s.tryComplete(); 722 } 723 } 724 725 static final class Merger extends CountedCompleter<Void> { 726 @java.io.Serial 727 static final long serialVersionUID = 2446542900576103244L; 728 final long[] a, w; // main and workspace arrays 729 final int lbase, lsize, rbase, rsize, wbase, gran; 730 Merger(CountedCompleter<?> par, long[] a, long[] w, 731 int lbase, int lsize, int rbase, 732 int rsize, int wbase, int gran) { 733 super(par); 734 this.a = a; this.w = w; 735 this.lbase = lbase; this.lsize = lsize; 736 this.rbase = rbase; this.rsize = rsize; 737 this.wbase = wbase; this.gran = gran; 738 } 739 740 public final void compute() { 741 long[] a = this.a, w = this.w; // localize all params 742 int lb = this.lbase, ln = this.lsize, rb = this.rbase, 743 rn = this.rsize, k = this.wbase, g = this.gran; 744 if (a == null || w == null || lb < 0 || rb < 0 || k < 0) 745 throw new IllegalStateException(); // hoist checks 746 for (int lh, rh;;) { // split larger, find point in smaller 785 if ((al = a[lb]) <= (ar = a[rb])) { 786 lb++; t = al; 787 } 788 else { 789 rb++; t = ar; 790 } 791 w[k++] = t; 792 } 793 if (rb < rf) 794 System.arraycopy(a, rb, w, k, rf - rb); 795 else if (lb < lf) 796 System.arraycopy(a, lb, w, k, lf - lb); 797 tryComplete(); 798 } 799 } 800 } // FJLong 801 802 /** float support class */ 803 static final class FJFloat { 804 static final class Sorter extends CountedCompleter<Void> { 805 @java.io.Serial 806 static final long serialVersionUID = 2446542900576103244L; 807 final float[] a, w; 808 final int base, size, wbase, gran; 809 Sorter(CountedCompleter<?> par, float[] a, float[] w, int base, 810 int size, int wbase, int gran) { 811 super(par); 812 this.a = a; this.w = w; this.base = base; this.size = size; 813 this.wbase = wbase; this.gran = gran; 814 } 815 public final void compute() { 816 CountedCompleter<?> s = this; 817 float[] a = this.a, w = this.w; // localize all params 818 int b = this.base, n = this.size, wb = this.wbase, g = this.gran; 819 while (n > g) { 820 int h = n >>> 1, q = h >>> 1, u = h + q; // quartiles 821 Relay fc = new Relay(new Merger(s, w, a, wb, h, 822 wb+h, n-h, b, g)); 823 Relay rc = new Relay(new Merger(fc, a, w, b+h, q, 824 b+u, n-u, wb+h, g)); 825 new Sorter(rc, a, w, b+u, n-u, wb+u, g).fork(); 826 new Sorter(rc, a, w, b+h, q, wb+h, g).fork();; 827 Relay bc = new Relay(new Merger(fc, a, w, b, q, 828 b+q, h-q, wb, g)); 829 new Sorter(bc, a, w, b+q, h-q, wb+q, g).fork(); 830 s = new EmptyCompleter(bc); 831 n = q; 832 } 833 DualPivotQuicksort.sort(a, b, b + n - 1, w, wb, n); 834 s.tryComplete(); 835 } 836 } 837 838 static final class Merger extends CountedCompleter<Void> { 839 @java.io.Serial 840 static final long serialVersionUID = 2446542900576103244L; 841 final float[] a, w; // main and workspace arrays 842 final int lbase, lsize, rbase, rsize, wbase, gran; 843 Merger(CountedCompleter<?> par, float[] a, float[] w, 844 int lbase, int lsize, int rbase, 845 int rsize, int wbase, int gran) { 846 super(par); 847 this.a = a; this.w = w; 848 this.lbase = lbase; this.lsize = lsize; 849 this.rbase = rbase; this.rsize = rsize; 850 this.wbase = wbase; this.gran = gran; 851 } 852 853 public final void compute() { 854 float[] a = this.a, w = this.w; // localize all params 855 int lb = this.lbase, ln = this.lsize, rb = this.rbase, 856 rn = this.rsize, k = this.wbase, g = this.gran; 857 if (a == null || w == null || lb < 0 || rb < 0 || k < 0) 858 throw new IllegalStateException(); // hoist checks 859 for (int lh, rh;;) { // split larger, find point in smaller 898 if ((al = a[lb]) <= (ar = a[rb])) { 899 lb++; t = al; 900 } 901 else { 902 rb++; t = ar; 903 } 904 w[k++] = t; 905 } 906 if (rb < rf) 907 System.arraycopy(a, rb, w, k, rf - rb); 908 else if (lb < lf) 909 System.arraycopy(a, lb, w, k, lf - lb); 910 tryComplete(); 911 } 912 } 913 } // FJFloat 914 915 /** double support class */ 916 static final class FJDouble { 917 static final class Sorter extends CountedCompleter<Void> { 918 @java.io.Serial 919 static final long serialVersionUID = 2446542900576103244L; 920 final double[] a, w; 921 final int base, size, wbase, gran; 922 Sorter(CountedCompleter<?> par, double[] a, double[] w, int base, 923 int size, int wbase, int gran) { 924 super(par); 925 this.a = a; this.w = w; this.base = base; this.size = size; 926 this.wbase = wbase; this.gran = gran; 927 } 928 public final void compute() { 929 CountedCompleter<?> s = this; 930 double[] a = this.a, w = this.w; // localize all params 931 int b = this.base, n = this.size, wb = this.wbase, g = this.gran; 932 while (n > g) { 933 int h = n >>> 1, q = h >>> 1, u = h + q; // quartiles 934 Relay fc = new Relay(new Merger(s, w, a, wb, h, 935 wb+h, n-h, b, g)); 936 Relay rc = new Relay(new Merger(fc, a, w, b+h, q, 937 b+u, n-u, wb+h, g)); 938 new Sorter(rc, a, w, b+u, n-u, wb+u, g).fork(); 939 new Sorter(rc, a, w, b+h, q, wb+h, g).fork();; 940 Relay bc = new Relay(new Merger(fc, a, w, b, q, 941 b+q, h-q, wb, g)); 942 new Sorter(bc, a, w, b+q, h-q, wb+q, g).fork(); 943 s = new EmptyCompleter(bc); 944 n = q; 945 } 946 DualPivotQuicksort.sort(a, b, b + n - 1, w, wb, n); 947 s.tryComplete(); 948 } 949 } 950 951 static final class Merger extends CountedCompleter<Void> { 952 @java.io.Serial 953 static final long serialVersionUID = 2446542900576103244L; 954 final double[] a, w; // main and workspace arrays 955 final int lbase, lsize, rbase, rsize, wbase, gran; 956 Merger(CountedCompleter<?> par, double[] a, double[] w, 957 int lbase, int lsize, int rbase, 958 int rsize, int wbase, int gran) { 959 super(par); 960 this.a = a; this.w = w; 961 this.lbase = lbase; this.lsize = lsize; 962 this.rbase = rbase; this.rsize = rsize; 963 this.wbase = wbase; this.gran = gran; 964 } 965 966 public final void compute() { 967 double[] a = this.a, w = this.w; // localize all params 968 int lb = this.lbase, ln = this.lsize, rb = this.rbase, 969 rn = this.rsize, k = this.wbase, g = this.gran; 970 if (a == null || w == null || lb < 0 || rb < 0 || k < 0) 971 throw new IllegalStateException(); // hoist checks 972 for (int lh, rh;;) { // split larger, find point in smaller |