src/java.base/share/classes/java/util/DualPivotQuicksort.java
author bchristi
Tue, 12 Nov 2019 13:49:40 -0800
changeset 59042 8910b995a2ee
parent 47216 71c04702a3d5
permissions -rw-r--r--
8226297: Dual-pivot quicksort improvements Reviewed-by: dl, lbourges Contributed-by: Vladimir Yaroslavskiy <vlv.spb.ru@mail.ru>
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
4170
a94a6faf44e6 6880672: Replace quicksort in java.util.Arrays with dual-pivot implementation
alanb
parents:
diff changeset
     1
/*
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
     2
 * Copyright (c) 2009, 2019, Oracle and/or its affiliates. All rights reserved.
4170
a94a6faf44e6 6880672: Replace quicksort in java.util.Arrays with dual-pivot implementation
alanb
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
a94a6faf44e6 6880672: Replace quicksort in java.util.Arrays with dual-pivot implementation
alanb
parents:
diff changeset
     4
 *
a94a6faf44e6 6880672: Replace quicksort in java.util.Arrays with dual-pivot implementation
alanb
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
a94a6faf44e6 6880672: Replace quicksort in java.util.Arrays with dual-pivot implementation
alanb
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 4980
diff changeset
     7
 * published by the Free Software Foundation.  Oracle designates this
4170
a94a6faf44e6 6880672: Replace quicksort in java.util.Arrays with dual-pivot implementation
alanb
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 4980
diff changeset
     9
 * by Oracle in the LICENSE file that accompanied this code.
4170
a94a6faf44e6 6880672: Replace quicksort in java.util.Arrays with dual-pivot implementation
alanb
parents:
diff changeset
    10
 *
a94a6faf44e6 6880672: Replace quicksort in java.util.Arrays with dual-pivot implementation
alanb
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
a94a6faf44e6 6880672: Replace quicksort in java.util.Arrays with dual-pivot implementation
alanb
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
a94a6faf44e6 6880672: Replace quicksort in java.util.Arrays with dual-pivot implementation
alanb
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
a94a6faf44e6 6880672: Replace quicksort in java.util.Arrays with dual-pivot implementation
alanb
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
a94a6faf44e6 6880672: Replace quicksort in java.util.Arrays with dual-pivot implementation
alanb
parents:
diff changeset
    15
 * accompanied this code).
a94a6faf44e6 6880672: Replace quicksort in java.util.Arrays with dual-pivot implementation
alanb
parents:
diff changeset
    16
 *
a94a6faf44e6 6880672: Replace quicksort in java.util.Arrays with dual-pivot implementation
alanb
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
a94a6faf44e6 6880672: Replace quicksort in java.util.Arrays with dual-pivot implementation
alanb
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
a94a6faf44e6 6880672: Replace quicksort in java.util.Arrays with dual-pivot implementation
alanb
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
a94a6faf44e6 6880672: Replace quicksort in java.util.Arrays with dual-pivot implementation
alanb
parents:
diff changeset
    20
 *
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 4980
diff changeset
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 4980
diff changeset
    22
 * or visit www.oracle.com if you need additional information or have any
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 4980
diff changeset
    23
 * questions.
4170
a94a6faf44e6 6880672: Replace quicksort in java.util.Arrays with dual-pivot implementation
alanb
parents:
diff changeset
    24
 */
a94a6faf44e6 6880672: Replace quicksort in java.util.Arrays with dual-pivot implementation
alanb
parents:
diff changeset
    25
a94a6faf44e6 6880672: Replace quicksort in java.util.Arrays with dual-pivot implementation
alanb
parents:
diff changeset
    26
package java.util;
a94a6faf44e6 6880672: Replace quicksort in java.util.Arrays with dual-pivot implementation
alanb
parents:
diff changeset
    27
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
    28
import java.util.concurrent.CountedCompleter;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
    29
import java.util.concurrent.RecursiveTask;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
    30
4170
a94a6faf44e6 6880672: Replace quicksort in java.util.Arrays with dual-pivot implementation
alanb
parents:
diff changeset
    31
/**
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
    32
 * This class implements powerful and fully optimized versions, both
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
    33
 * sequential and parallel, of the Dual-Pivot Quicksort algorithm by
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
    34
 * Vladimir Yaroslavskiy, Jon Bentley and Josh Bloch. This algorithm
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
    35
 * offers O(n log(n)) performance on all data sets, and is typically
4170
a94a6faf44e6 6880672: Replace quicksort in java.util.Arrays with dual-pivot implementation
alanb
parents:
diff changeset
    36
 * faster than traditional (one-pivot) Quicksort implementations.
a94a6faf44e6 6880672: Replace quicksort in java.util.Arrays with dual-pivot implementation
alanb
parents:
diff changeset
    37
 *
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
    38
 * There are also additional algorithms, invoked from the Dual-Pivot
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
    39
 * Quicksort, such as mixed insertion sort, merging of runs and heap
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
    40
 * sort, counting sort and parallel merge sort.
17712
b56c69500af6 8014076: Arrays parallel and serial sorting improvements
dl
parents: 9035
diff changeset
    41
 *
4170
a94a6faf44e6 6880672: Replace quicksort in java.util.Arrays with dual-pivot implementation
alanb
parents:
diff changeset
    42
 * @author Vladimir Yaroslavskiy
a94a6faf44e6 6880672: Replace quicksort in java.util.Arrays with dual-pivot implementation
alanb
parents:
diff changeset
    43
 * @author Jon Bentley
a94a6faf44e6 6880672: Replace quicksort in java.util.Arrays with dual-pivot implementation
alanb
parents:
diff changeset
    44
 * @author Josh Bloch
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
    45
 * @author Doug Lea
4170
a94a6faf44e6 6880672: Replace quicksort in java.util.Arrays with dual-pivot implementation
alanb
parents:
diff changeset
    46
 *
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
    47
 * @version 2018.08.18
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
    48
 *
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
    49
 * @since 1.7 * 14
4170
a94a6faf44e6 6880672: Replace quicksort in java.util.Arrays with dual-pivot implementation
alanb
parents:
diff changeset
    50
 */
a94a6faf44e6 6880672: Replace quicksort in java.util.Arrays with dual-pivot implementation
alanb
parents:
diff changeset
    51
final class DualPivotQuicksort {
a94a6faf44e6 6880672: Replace quicksort in java.util.Arrays with dual-pivot implementation
alanb
parents:
diff changeset
    52
4241
7d4f50f3806c 6901318: Yet more Dual-pivot quicksort improvements
alanb
parents: 4233
diff changeset
    53
    /**
4356
1f9c2400b8c5 6905046: More Dual-pivot quicksort improvements
jjb
parents: 4241
diff changeset
    54
     * Prevents instantiation.
4241
7d4f50f3806c 6901318: Yet more Dual-pivot quicksort improvements
alanb
parents: 4233
diff changeset
    55
     */
4170
a94a6faf44e6 6880672: Replace quicksort in java.util.Arrays with dual-pivot implementation
alanb
parents:
diff changeset
    56
    private DualPivotQuicksort() {}
a94a6faf44e6 6880672: Replace quicksort in java.util.Arrays with dual-pivot implementation
alanb
parents:
diff changeset
    57
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
    58
    /**
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
    59
     * Max array size to use mixed insertion sort.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
    60
     */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
    61
    private static final int MAX_MIXED_INSERTION_SORT_SIZE = 65;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
    62
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
    63
    /**
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
    64
     * Max array size to use insertion sort.
4170
a94a6faf44e6 6880672: Replace quicksort in java.util.Arrays with dual-pivot implementation
alanb
parents:
diff changeset
    65
     */
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
    66
    private static final int MAX_INSERTION_SORT_SIZE = 44;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
    67
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
    68
    /**
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
    69
     * Min array size to perform sorting in parallel.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
    70
     */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
    71
    private static final int MIN_PARALLEL_SORT_SIZE = 4 << 10;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
    72
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
    73
    /**
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
    74
     * Min array size to try merging of runs.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
    75
     */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
    76
    private static final int MIN_TRY_MERGE_SIZE = 4 << 10;
4170
a94a6faf44e6 6880672: Replace quicksort in java.util.Arrays with dual-pivot implementation
alanb
parents:
diff changeset
    77
a94a6faf44e6 6880672: Replace quicksort in java.util.Arrays with dual-pivot implementation
alanb
parents:
diff changeset
    78
    /**
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
    79
     * Min size of the first run to continue with scanning.
8188
b90884cf34f5 7013585: Dual-pivot quicksort improvements for highly structured (nearly sorted) and data with small periods
alanb
parents: 6896
diff changeset
    80
     */
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
    81
    private static final int MIN_FIRST_RUN_SIZE = 16;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
    82
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
    83
    /**
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
    84
     * Min factor for the first runs to continue scanning.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
    85
     */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
    86
    private static final int MIN_FIRST_RUNS_FACTOR = 7;
8188
b90884cf34f5 7013585: Dual-pivot quicksort improvements for highly structured (nearly sorted) and data with small periods
alanb
parents: 6896
diff changeset
    87
b90884cf34f5 7013585: Dual-pivot quicksort improvements for highly structured (nearly sorted) and data with small periods
alanb
parents: 6896
diff changeset
    88
    /**
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
    89
     * Max capacity of the index array for tracking runs.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
    90
     */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
    91
    private static final int MAX_RUN_CAPACITY = 5 << 10;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
    92
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
    93
    /**
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
    94
     * Min number of runs, required by parallel merging.
8188
b90884cf34f5 7013585: Dual-pivot quicksort improvements for highly structured (nearly sorted) and data with small periods
alanb
parents: 6896
diff changeset
    95
     */
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
    96
    private static final int MIN_RUN_COUNT = 4;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
    97
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
    98
    /**
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
    99
     * Min array size to use parallel merging of parts.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   100
     */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   101
    private static final int MIN_PARALLEL_MERGE_PARTS_SIZE = 4 << 10;
8188
b90884cf34f5 7013585: Dual-pivot quicksort improvements for highly structured (nearly sorted) and data with small periods
alanb
parents: 6896
diff changeset
   102
b90884cf34f5 7013585: Dual-pivot quicksort improvements for highly structured (nearly sorted) and data with small periods
alanb
parents: 6896
diff changeset
   103
    /**
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   104
     * Min size of a byte array to use counting sort.
4170
a94a6faf44e6 6880672: Replace quicksort in java.util.Arrays with dual-pivot implementation
alanb
parents:
diff changeset
   105
     */
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   106
    private static final int MIN_BYTE_COUNTING_SORT_SIZE = 64;
4170
a94a6faf44e6 6880672: Replace quicksort in java.util.Arrays with dual-pivot implementation
alanb
parents:
diff changeset
   107
a94a6faf44e6 6880672: Replace quicksort in java.util.Arrays with dual-pivot implementation
alanb
parents:
diff changeset
   108
    /**
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   109
     * Min size of a short or char array to use counting sort.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   110
     */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   111
    private static final int MIN_SHORT_OR_CHAR_COUNTING_SORT_SIZE = 1750;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   112
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   113
    /**
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   114
     * Threshold of mixed insertion sort is incremented by this value.
4170
a94a6faf44e6 6880672: Replace quicksort in java.util.Arrays with dual-pivot implementation
alanb
parents:
diff changeset
   115
     */
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   116
    private static final int DELTA = 3 << 1;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   117
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   118
    /**
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   119
     * Max recursive partitioning depth before using heap sort.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   120
     */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   121
    private static final int MAX_RECURSION_DEPTH = 64 * DELTA;
4170
a94a6faf44e6 6880672: Replace quicksort in java.util.Arrays with dual-pivot implementation
alanb
parents:
diff changeset
   122
a94a6faf44e6 6880672: Replace quicksort in java.util.Arrays with dual-pivot implementation
alanb
parents:
diff changeset
   123
    /**
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   124
     * Calculates the double depth of parallel merging.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   125
     * Depth is negative, if tasks split before sorting.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   126
     *
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   127
     * @param parallelism the parallelism level
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   128
     * @param size the target size
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   129
     * @return the depth of parallel merging
4170
a94a6faf44e6 6880672: Replace quicksort in java.util.Arrays with dual-pivot implementation
alanb
parents:
diff changeset
   130
     */
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   131
    private static int getDepth(int parallelism, int size) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   132
        int depth = 0;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   133
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   134
        while ((parallelism >>= 3) > 0 && (size >>= 2) > 0) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   135
            depth -= 2;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   136
        }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   137
        return depth;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   138
    }
4170
a94a6faf44e6 6880672: Replace quicksort in java.util.Arrays with dual-pivot implementation
alanb
parents:
diff changeset
   139
a94a6faf44e6 6880672: Replace quicksort in java.util.Arrays with dual-pivot implementation
alanb
parents:
diff changeset
   140
    /**
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   141
     * Sorts the specified range of the array using parallel merge
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   142
     * sort and/or Dual-Pivot Quicksort.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   143
     *
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   144
     * To balance the faster splitting and parallelism of merge sort
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   145
     * with the faster element partitioning of Quicksort, ranges are
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   146
     * subdivided in tiers such that, if there is enough parallelism,
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   147
     * the four-way parallel merge is started, still ensuring enough
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   148
     * parallelism to process the partitions.
4233
9b594a48d0f4 6899694: Dual-pivot quicksort improvements
alanb
parents: 4177
diff changeset
   149
     *
9b594a48d0f4 6899694: Dual-pivot quicksort improvements
alanb
parents: 4177
diff changeset
   150
     * @param a the array to be sorted
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   151
     * @param parallelism the parallelism level
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   152
     * @param low the index of the first element, inclusive, to be sorted
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   153
     * @param high the index of the last element, exclusive, to be sorted
6896
d229d56fd918 6976036: Dual-pivot quicksort update (10/2010 tune-up)
alanb
parents: 5995
diff changeset
   154
     */
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   155
    static void sort(int[] a, int parallelism, int low, int high) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   156
        int size = high - low;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   157
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   158
        if (parallelism > 1 && size > MIN_PARALLEL_SORT_SIZE) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   159
            int depth = getDepth(parallelism, size >> 12);
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   160
            int[] b = depth == 0 ? null : new int[size];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   161
            new Sorter(null, a, b, low, size, low, depth).invoke();
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   162
        } else {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   163
            sort(null, a, 0, low, high);
8188
b90884cf34f5 7013585: Dual-pivot quicksort improvements for highly structured (nearly sorted) and data with small periods
alanb
parents: 6896
diff changeset
   164
        }
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   165
    }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   166
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   167
    /**
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   168
     * Sorts the specified array using the Dual-Pivot Quicksort and/or
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   169
     * other sorts in special-cases, possibly with parallel partitions.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   170
     *
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   171
     * @param sorter parallel context
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   172
     * @param a the array to be sorted
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   173
     * @param bits the combination of recursion depth and bit flag, where
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   174
     *        the right bit "0" indicates that array is the leftmost part
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   175
     * @param low the index of the first element, inclusive, to be sorted
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   176
     * @param high the index of the last element, exclusive, to be sorted
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   177
     */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   178
    static void sort(Sorter sorter, int[] a, int bits, int low, int high) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   179
        while (true) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   180
            int end = high - 1, size = high - low;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   181
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   182
            /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   183
             * Run mixed insertion sort on small non-leftmost parts.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   184
             */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   185
            if (size < MAX_MIXED_INSERTION_SORT_SIZE + bits && (bits & 1) > 0) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   186
                mixedInsertionSort(a, low, high - 3 * ((size >> 5) << 3), high);
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   187
                return;
31079
bf5fabb914b6 8080945: Improve the performance of primitive Arrays.sort for certain patterns of array elements
psandoz
parents: 25859
diff changeset
   188
            }
bf5fabb914b6 8080945: Improve the performance of primitive Arrays.sort for certain patterns of array elements
psandoz
parents: 25859
diff changeset
   189
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   190
            /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   191
             * Invoke insertion sort on small leftmost part.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   192
             */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   193
            if (size < MAX_INSERTION_SORT_SIZE) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   194
                insertionSort(a, low, high);
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   195
                return;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   196
            }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   197
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   198
            /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   199
             * Check if the whole array or large non-leftmost
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   200
             * parts are nearly sorted and then merge runs.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   201
             */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   202
            if ((bits == 0 || size > MIN_TRY_MERGE_SIZE && (bits & 1) > 0)
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   203
                    && tryMergeRuns(sorter, a, low, size)) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   204
                return;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   205
            }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   206
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   207
            /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   208
             * Switch to heap sort if execution
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   209
             * time is becoming quadratic.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   210
             */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   211
            if ((bits += DELTA) > MAX_RECURSION_DEPTH) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   212
                heapSort(a, low, high);
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   213
                return;
8188
b90884cf34f5 7013585: Dual-pivot quicksort improvements for highly structured (nearly sorted) and data with small periods
alanb
parents: 6896
diff changeset
   214
            }
b90884cf34f5 7013585: Dual-pivot quicksort improvements for highly structured (nearly sorted) and data with small periods
alanb
parents: 6896
diff changeset
   215
b90884cf34f5 7013585: Dual-pivot quicksort improvements for highly structured (nearly sorted) and data with small periods
alanb
parents: 6896
diff changeset
   216
            /*
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   217
             * Use an inexpensive approximation of the golden ratio
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   218
             * to select five sample elements and determine pivots.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   219
             */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   220
            int step = (size >> 3) * 3 + 3;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   221
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   222
            /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   223
             * Five elements around (and including) the central element
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   224
             * will be used for pivot selection as described below. The
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   225
             * unequal choice of spacing these elements was empirically
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   226
             * determined to work well on a wide variety of inputs.
8188
b90884cf34f5 7013585: Dual-pivot quicksort improvements for highly structured (nearly sorted) and data with small periods
alanb
parents: 6896
diff changeset
   227
             */
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   228
            int e1 = low + step;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   229
            int e5 = end - step;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   230
            int e3 = (e1 + e5) >>> 1;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   231
            int e2 = (e1 + e3) >>> 1;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   232
            int e4 = (e3 + e5) >>> 1;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   233
            int a3 = a[e3];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   234
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   235
            /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   236
             * Sort these elements in place by the combination
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   237
             * of 4-element sorting network and insertion sort.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   238
             *
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   239
             *    5 ------o-----------o------------
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   240
             *            |           |
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   241
             *    4 ------|-----o-----o-----o------
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   242
             *            |     |           |
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   243
             *    2 ------o-----|-----o-----o------
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   244
             *                  |     |
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   245
             *    1 ------------o-----o------------
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   246
             */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   247
            if (a[e5] < a[e2]) { int t = a[e5]; a[e5] = a[e2]; a[e2] = t; }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   248
            if (a[e4] < a[e1]) { int t = a[e4]; a[e4] = a[e1]; a[e1] = t; }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   249
            if (a[e5] < a[e4]) { int t = a[e5]; a[e5] = a[e4]; a[e4] = t; }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   250
            if (a[e2] < a[e1]) { int t = a[e2]; a[e2] = a[e1]; a[e1] = t; }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   251
            if (a[e4] < a[e2]) { int t = a[e4]; a[e4] = a[e2]; a[e2] = t; }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   252
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   253
            if (a3 < a[e2]) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   254
                if (a3 < a[e1]) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   255
                    a[e3] = a[e2]; a[e2] = a[e1]; a[e1] = a3;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   256
                } else {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   257
                    a[e3] = a[e2]; a[e2] = a3;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   258
                }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   259
            } else if (a3 > a[e4]) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   260
                if (a3 > a[e5]) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   261
                    a[e3] = a[e4]; a[e4] = a[e5]; a[e5] = a3;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   262
                } else {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   263
                    a[e3] = a[e4]; a[e4] = a3;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   264
                }
8188
b90884cf34f5 7013585: Dual-pivot quicksort improvements for highly structured (nearly sorted) and data with small periods
alanb
parents: 6896
diff changeset
   265
            }
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   266
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   267
            // Pointers
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   268
            int lower = low; // The index of the last element of the left part
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   269
            int upper = end; // The index of the first element of the right part
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   270
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   271
            /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   272
             * Partitioning with 2 pivots in case of different elements.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   273
             */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   274
            if (a[e1] < a[e2] && a[e2] < a[e3] && a[e3] < a[e4] && a[e4] < a[e5]) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   275
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   276
                /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   277
                 * Use the first and fifth of the five sorted elements as
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   278
                 * the pivots. These values are inexpensive approximation
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   279
                 * of tertiles. Note, that pivot1 < pivot2.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   280
                 */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   281
                int pivot1 = a[e1];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   282
                int pivot2 = a[e5];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   283
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   284
                /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   285
                 * The first and the last elements to be sorted are moved
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   286
                 * to the locations formerly occupied by the pivots. When
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   287
                 * partitioning is completed, the pivots are swapped back
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   288
                 * into their final positions, and excluded from the next
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   289
                 * subsequent sorting.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   290
                 */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   291
                a[e1] = a[lower];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   292
                a[e5] = a[upper];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   293
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   294
                /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   295
                 * Skip elements, which are less or greater than the pivots.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   296
                 */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   297
                while (a[++lower] < pivot1);
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   298
                while (a[--upper] > pivot2);
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   299
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   300
                /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   301
                 * Backward 3-interval partitioning
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   302
                 *
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   303
                 *   left part                 central part          right part
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   304
                 * +------------------------------------------------------------+
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   305
                 * |  < pivot1  |   ?   |  pivot1 <= && <= pivot2  |  > pivot2  |
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   306
                 * +------------------------------------------------------------+
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   307
                 *             ^       ^                            ^
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   308
                 *             |       |                            |
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   309
                 *           lower     k                          upper
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   310
                 *
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   311
                 * Invariants:
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   312
                 *
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   313
                 *              all in (low, lower] < pivot1
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   314
                 *    pivot1 <= all in (k, upper)  <= pivot2
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   315
                 *              all in [upper, end) > pivot2
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   316
                 *
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   317
                 * Pointer k is the last index of ?-part
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   318
                 */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   319
                for (int unused = --lower, k = ++upper; --k > lower; ) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   320
                    int ak = a[k];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   321
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   322
                    if (ak < pivot1) { // Move a[k] to the left side
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   323
                        while (lower < k) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   324
                            if (a[++lower] >= pivot1) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   325
                                if (a[lower] > pivot2) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   326
                                    a[k] = a[--upper];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   327
                                    a[upper] = a[lower];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   328
                                } else {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   329
                                    a[k] = a[lower];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   330
                                }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   331
                                a[lower] = ak;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   332
                                break;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   333
                            }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   334
                        }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   335
                    } else if (ak > pivot2) { // Move a[k] to the right side
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   336
                        a[k] = a[--upper];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   337
                        a[upper] = ak;
8188
b90884cf34f5 7013585: Dual-pivot quicksort improvements for highly structured (nearly sorted) and data with small periods
alanb
parents: 6896
diff changeset
   338
                    }
b90884cf34f5 7013585: Dual-pivot quicksort improvements for highly structured (nearly sorted) and data with small periods
alanb
parents: 6896
diff changeset
   339
                }
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   340
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   341
                /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   342
                 * Swap the pivots into their final positions.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   343
                 */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   344
                a[low] = a[lower]; a[lower] = pivot1;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   345
                a[end] = a[upper]; a[upper] = pivot2;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   346
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   347
                /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   348
                 * Sort non-left parts recursively (possibly in parallel),
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   349
                 * excluding known pivots.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   350
                 */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   351
                if (size > MIN_PARALLEL_SORT_SIZE && sorter != null) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   352
                    sorter.forkSorter(bits | 1, lower + 1, upper);
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   353
                    sorter.forkSorter(bits | 1, upper + 1, high);
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   354
                } else {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   355
                    sort(sorter, a, bits | 1, lower + 1, upper);
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   356
                    sort(sorter, a, bits | 1, upper + 1, high);
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   357
                }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   358
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   359
            } else { // Use single pivot in case of many equal elements
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   360
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   361
                /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   362
                 * Use the third of the five sorted elements as the pivot.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   363
                 * This value is inexpensive approximation of the median.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   364
                 */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   365
                int pivot = a[e3];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   366
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   367
                /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   368
                 * The first element to be sorted is moved to the
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   369
                 * location formerly occupied by the pivot. After
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   370
                 * completion of partitioning the pivot is swapped
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   371
                 * back into its final position, and excluded from
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   372
                 * the next subsequent sorting.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   373
                 */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   374
                a[e3] = a[lower];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   375
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   376
                /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   377
                 * Traditional 3-way (Dutch National Flag) partitioning
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   378
                 *
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   379
                 *   left part                 central part    right part
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   380
                 * +------------------------------------------------------+
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   381
                 * |   < pivot   |     ?     |   == pivot   |   > pivot   |
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   382
                 * +------------------------------------------------------+
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   383
                 *              ^           ^                ^
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   384
                 *              |           |                |
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   385
                 *            lower         k              upper
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   386
                 *
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   387
                 * Invariants:
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   388
                 *
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   389
                 *   all in (low, lower] < pivot
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   390
                 *   all in (k, upper)  == pivot
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   391
                 *   all in [upper, end] > pivot
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   392
                 *
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   393
                 * Pointer k is the last index of ?-part
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   394
                 */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   395
                for (int k = ++upper; --k > lower; ) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   396
                    int ak = a[k];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   397
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   398
                    if (ak != pivot) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   399
                        a[k] = pivot;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   400
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   401
                        if (ak < pivot) { // Move a[k] to the left side
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   402
                            while (a[++lower] < pivot);
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   403
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   404
                            if (a[lower] > pivot) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   405
                                a[--upper] = a[lower];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   406
                            }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   407
                            a[lower] = ak;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   408
                        } else { // ak > pivot - Move a[k] to the right side
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   409
                            a[--upper] = ak;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   410
                        }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   411
                    }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   412
                }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   413
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   414
                /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   415
                 * Swap the pivot into its final position.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   416
                 */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   417
                a[low] = a[lower]; a[lower] = pivot;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   418
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   419
                /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   420
                 * Sort the right part (possibly in parallel), excluding
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   421
                 * known pivot. All elements from the central part are
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   422
                 * equal and therefore already sorted.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   423
                 */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   424
                if (size > MIN_PARALLEL_SORT_SIZE && sorter != null) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   425
                    sorter.forkSorter(bits | 1, upper, high);
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   426
                } else {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   427
                    sort(sorter, a, bits | 1, upper, high);
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   428
                }
8188
b90884cf34f5 7013585: Dual-pivot quicksort improvements for highly structured (nearly sorted) and data with small periods
alanb
parents: 6896
diff changeset
   429
            }
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   430
            high = lower; // Iterate along the left part
8188
b90884cf34f5 7013585: Dual-pivot quicksort improvements for highly structured (nearly sorted) and data with small periods
alanb
parents: 6896
diff changeset
   431
        }
6896
d229d56fd918 6976036: Dual-pivot quicksort update (10/2010 tune-up)
alanb
parents: 5995
diff changeset
   432
    }
d229d56fd918 6976036: Dual-pivot quicksort update (10/2010 tune-up)
alanb
parents: 5995
diff changeset
   433
d229d56fd918 6976036: Dual-pivot quicksort update (10/2010 tune-up)
alanb
parents: 5995
diff changeset
   434
    /**
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   435
     * Sorts the specified range of the array using mixed insertion sort.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   436
     *
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   437
     * Mixed insertion sort is combination of simple insertion sort,
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   438
     * pin insertion sort and pair insertion sort.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   439
     *
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   440
     * In the context of Dual-Pivot Quicksort, the pivot element
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   441
     * from the left part plays the role of sentinel, because it
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   442
     * is less than any elements from the given part. Therefore,
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   443
     * expensive check of the left range can be skipped on each
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   444
     * iteration unless it is the leftmost call.
6896
d229d56fd918 6976036: Dual-pivot quicksort update (10/2010 tune-up)
alanb
parents: 5995
diff changeset
   445
     *
d229d56fd918 6976036: Dual-pivot quicksort update (10/2010 tune-up)
alanb
parents: 5995
diff changeset
   446
     * @param a the array to be sorted
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   447
     * @param low the index of the first element, inclusive, to be sorted
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   448
     * @param end the index of the last element for simple insertion sort
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   449
     * @param high the index of the last element, exclusive, to be sorted
4233
9b594a48d0f4 6899694: Dual-pivot quicksort improvements
alanb
parents: 4177
diff changeset
   450
     */
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   451
    private static void mixedInsertionSort(int[] a, int low, int end, int high) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   452
        if (end == high) {
8188
b90884cf34f5 7013585: Dual-pivot quicksort improvements for highly structured (nearly sorted) and data with small periods
alanb
parents: 6896
diff changeset
   453
5995
0b76e67c2054 6947216: Even more Dual-pivot quicksort improvements
alanb
parents: 5506
diff changeset
   454
            /*
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   455
             * Invoke simple insertion sort on tiny array.
5995
0b76e67c2054 6947216: Even more Dual-pivot quicksort improvements
alanb
parents: 5506
diff changeset
   456
             */
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   457
            for (int i; ++low < end; ) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   458
                int ai = a[i = low];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   459
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   460
                while (ai < a[--i]) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   461
                    a[i + 1] = a[i];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   462
                }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   463
                a[i + 1] = ai;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   464
            }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   465
        } else {
5995
0b76e67c2054 6947216: Even more Dual-pivot quicksort improvements
alanb
parents: 5506
diff changeset
   466
4170
a94a6faf44e6 6880672: Replace quicksort in java.util.Arrays with dual-pivot implementation
alanb
parents:
diff changeset
   467
            /*
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   468
             * Start with pin insertion sort on small part.
4170
a94a6faf44e6 6880672: Replace quicksort in java.util.Arrays with dual-pivot implementation
alanb
parents:
diff changeset
   469
             *
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   470
             * Pin insertion sort is extended simple insertion sort.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   471
             * The main idea of this sort is to put elements larger
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   472
             * than an element called pin to the end of array (the
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   473
             * proper area for such elements). It avoids expensive
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   474
             * movements of these elements through the whole array.
5995
0b76e67c2054 6947216: Even more Dual-pivot quicksort improvements
alanb
parents: 5506
diff changeset
   475
             */
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   476
            int pin = a[end];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   477
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   478
            for (int i, p = high; ++low < end; ) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   479
                int ai = a[i = low];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   480
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   481
                if (ai < a[i - 1]) { // Small element
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   482
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   483
                    /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   484
                     * Insert small element into sorted part.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   485
                     */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   486
                    a[i] = a[--i];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   487
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   488
                    while (ai < a[--i]) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   489
                        a[i + 1] = a[i];
4170
a94a6faf44e6 6880672: Replace quicksort in java.util.Arrays with dual-pivot implementation
alanb
parents:
diff changeset
   490
                    }
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   491
                    a[i + 1] = ai;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   492
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   493
                } else if (p > i && ai > pin) { // Large element
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   494
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   495
                    /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   496
                     * Find element smaller than pin.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   497
                     */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   498
                    while (a[--p] > pin);
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   499
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   500
                    /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   501
                     * Swap it with large element.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   502
                     */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   503
                    if (p > i) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   504
                        ai = a[p];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   505
                        a[p] = a[i];
4170
a94a6faf44e6 6880672: Replace quicksort in java.util.Arrays with dual-pivot implementation
alanb
parents:
diff changeset
   506
                    }
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   507
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   508
                    /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   509
                     * Insert small element into sorted part.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   510
                     */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   511
                    while (ai < a[--i]) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   512
                        a[i + 1] = a[i];
4170
a94a6faf44e6 6880672: Replace quicksort in java.util.Arrays with dual-pivot implementation
alanb
parents:
diff changeset
   513
                    }
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   514
                    a[i + 1] = ai;
4170
a94a6faf44e6 6880672: Replace quicksort in java.util.Arrays with dual-pivot implementation
alanb
parents:
diff changeset
   515
                }
a94a6faf44e6 6880672: Replace quicksort in java.util.Arrays with dual-pivot implementation
alanb
parents:
diff changeset
   516
            }
4356
1f9c2400b8c5 6905046: More Dual-pivot quicksort improvements
jjb
parents: 4241
diff changeset
   517
6896
d229d56fd918 6976036: Dual-pivot quicksort update (10/2010 tune-up)
alanb
parents: 5995
diff changeset
   518
            /*
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   519
             * Continue with pair insertion sort on remain part.
6896
d229d56fd918 6976036: Dual-pivot quicksort update (10/2010 tune-up)
alanb
parents: 5995
diff changeset
   520
             */
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   521
            for (int i; low < high; ++low) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   522
                int a1 = a[i = low], a2 = a[++low];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   523
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   524
                /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   525
                 * Insert two elements per iteration: at first, insert the
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   526
                 * larger element and then insert the smaller element, but
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   527
                 * from the position where the larger element was inserted.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   528
                 */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   529
                if (a1 > a2) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   530
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   531
                    while (a1 < a[--i]) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   532
                        a[i + 2] = a[i];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   533
                    }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   534
                    a[++i + 1] = a1;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   535
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   536
                    while (a2 < a[--i]) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   537
                        a[i + 1] = a[i];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   538
                    }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   539
                    a[i + 1] = a2;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   540
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   541
                } else if (a1 < a[i - 1]) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   542
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   543
                    while (a2 < a[--i]) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   544
                        a[i + 2] = a[i];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   545
                    }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   546
                    a[++i + 1] = a2;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   547
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   548
                    while (a1 < a[--i]) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   549
                        a[i + 1] = a[i];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   550
                    }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   551
                    a[i + 1] = a1;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   552
                }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   553
            }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   554
        }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   555
    }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   556
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   557
    /**
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   558
     * Sorts the specified range of the array using insertion sort.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   559
     *
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   560
     * @param a the array to be sorted
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   561
     * @param low the index of the first element, inclusive, to be sorted
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   562
     * @param high the index of the last element, exclusive, to be sorted
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   563
     */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   564
    private static void insertionSort(int[] a, int low, int high) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   565
        for (int i, k = low; ++k < high; ) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   566
            int ai = a[i = k];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   567
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   568
            if (ai < a[i - 1]) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   569
                while (--i >= low && ai < a[i]) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   570
                    a[i + 1] = a[i];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   571
                }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   572
                a[i + 1] = ai;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   573
            }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   574
        }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   575
    }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   576
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   577
    /**
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   578
     * Sorts the specified range of the array using heap sort.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   579
     *
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   580
     * @param a the array to be sorted
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   581
     * @param low the index of the first element, inclusive, to be sorted
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   582
     * @param high the index of the last element, exclusive, to be sorted
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   583
     */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   584
    private static void heapSort(int[] a, int low, int high) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   585
        for (int k = (low + high) >>> 1; k > low; ) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   586
            pushDown(a, --k, a[k], low, high);
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   587
        }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   588
        while (--high > low) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   589
            int max = a[low];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   590
            pushDown(a, low, a[high], low, high);
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   591
            a[high] = max;
4170
a94a6faf44e6 6880672: Replace quicksort in java.util.Arrays with dual-pivot implementation
alanb
parents:
diff changeset
   592
        }
4233
9b594a48d0f4 6899694: Dual-pivot quicksort improvements
alanb
parents: 4177
diff changeset
   593
    }
9b594a48d0f4 6899694: Dual-pivot quicksort improvements
alanb
parents: 4177
diff changeset
   594
9b594a48d0f4 6899694: Dual-pivot quicksort improvements
alanb
parents: 4177
diff changeset
   595
    /**
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   596
     * Pushes specified element down during heap sort.
4233
9b594a48d0f4 6899694: Dual-pivot quicksort improvements
alanb
parents: 4177
diff changeset
   597
     *
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   598
     * @param a the given array
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   599
     * @param p the start index
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   600
     * @param value the given element
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   601
     * @param low the index of the first element, inclusive, to be sorted
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   602
     * @param high the index of the last element, exclusive, to be sorted
6896
d229d56fd918 6976036: Dual-pivot quicksort update (10/2010 tune-up)
alanb
parents: 5995
diff changeset
   603
     */
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   604
    private static void pushDown(int[] a, int p, int value, int low, int high) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   605
        for (int k ;; a[p] = a[p = k]) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   606
            k = (p << 1) - low + 2; // Index of the right child
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   607
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   608
            if (k > high) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   609
                break;
31079
bf5fabb914b6 8080945: Improve the performance of primitive Arrays.sort for certain patterns of array elements
psandoz
parents: 25859
diff changeset
   610
            }
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   611
            if (k == high || a[k] < a[k - 1]) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   612
                --k;
8188
b90884cf34f5 7013585: Dual-pivot quicksort improvements for highly structured (nearly sorted) and data with small periods
alanb
parents: 6896
diff changeset
   613
            }
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   614
            if (a[k] <= value) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   615
                break;
8188
b90884cf34f5 7013585: Dual-pivot quicksort improvements for highly structured (nearly sorted) and data with small periods
alanb
parents: 6896
diff changeset
   616
            }
b90884cf34f5 7013585: Dual-pivot quicksort improvements for highly structured (nearly sorted) and data with small periods
alanb
parents: 6896
diff changeset
   617
        }
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   618
        a[p] = value;
6896
d229d56fd918 6976036: Dual-pivot quicksort update (10/2010 tune-up)
alanb
parents: 5995
diff changeset
   619
    }
d229d56fd918 6976036: Dual-pivot quicksort update (10/2010 tune-up)
alanb
parents: 5995
diff changeset
   620
d229d56fd918 6976036: Dual-pivot quicksort update (10/2010 tune-up)
alanb
parents: 5995
diff changeset
   621
    /**
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   622
     * Tries to sort the specified range of the array.
6896
d229d56fd918 6976036: Dual-pivot quicksort update (10/2010 tune-up)
alanb
parents: 5995
diff changeset
   623
     *
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   624
     * @param sorter parallel context
6896
d229d56fd918 6976036: Dual-pivot quicksort update (10/2010 tune-up)
alanb
parents: 5995
diff changeset
   625
     * @param a the array to be sorted
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   626
     * @param low the index of the first element to be sorted
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   627
     * @param size the array size
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   628
     * @return true if finally sorted, false otherwise
4233
9b594a48d0f4 6899694: Dual-pivot quicksort improvements
alanb
parents: 4177
diff changeset
   629
     */
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   630
    private static boolean tryMergeRuns(Sorter sorter, int[] a, int low, int size) {
5995
0b76e67c2054 6947216: Even more Dual-pivot quicksort improvements
alanb
parents: 5506
diff changeset
   631
0b76e67c2054 6947216: Even more Dual-pivot quicksort improvements
alanb
parents: 5506
diff changeset
   632
        /*
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   633
         * The run array is constructed only if initial runs are
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   634
         * long enough to continue, run[i] then holds start index
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   635
         * of the i-th sequence of elements in non-descending order.
5995
0b76e67c2054 6947216: Even more Dual-pivot quicksort improvements
alanb
parents: 5506
diff changeset
   636
         */
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   637
        int[] run = null;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   638
        int high = low + size;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   639
        int count = 1, last = low;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   640
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   641
        /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   642
         * Identify all possible runs.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   643
         */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   644
        for (int k = low + 1; k < high; ) {
5995
0b76e67c2054 6947216: Even more Dual-pivot quicksort improvements
alanb
parents: 5506
diff changeset
   645
4170
a94a6faf44e6 6880672: Replace quicksort in java.util.Arrays with dual-pivot implementation
alanb
parents:
diff changeset
   646
            /*
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   647
             * Find the end index of the current run.
4170
a94a6faf44e6 6880672: Replace quicksort in java.util.Arrays with dual-pivot implementation
alanb
parents:
diff changeset
   648
             */
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   649
            if (a[k - 1] < a[k]) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   650
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   651
                // Identify ascending sequence
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   652
                while (++k < high && a[k - 1] <= a[k]);
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   653
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   654
            } else if (a[k - 1] > a[k]) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   655
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   656
                // Identify descending sequence
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   657
                while (++k < high && a[k - 1] >= a[k]);
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   658
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   659
                // Reverse into ascending order
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   660
                for (int i = last - 1, j = k; ++i < --j && a[i] > a[j]; ) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   661
                    int ai = a[i]; a[i] = a[j]; a[j] = ai;
5995
0b76e67c2054 6947216: Even more Dual-pivot quicksort improvements
alanb
parents: 5506
diff changeset
   662
                }
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   663
            } else { // Identify constant sequence
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   664
                for (int ak = a[k]; ++k < high && ak == a[k]; );
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   665
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   666
                if (k < high) {
4241
7d4f50f3806c 6901318: Yet more Dual-pivot quicksort improvements
alanb
parents: 4233
diff changeset
   667
                    continue;
4170
a94a6faf44e6 6880672: Replace quicksort in java.util.Arrays with dual-pivot implementation
alanb
parents:
diff changeset
   668
                }
a94a6faf44e6 6880672: Replace quicksort in java.util.Arrays with dual-pivot implementation
alanb
parents:
diff changeset
   669
            }
4356
1f9c2400b8c5 6905046: More Dual-pivot quicksort improvements
jjb
parents: 4241
diff changeset
   670
6896
d229d56fd918 6976036: Dual-pivot quicksort update (10/2010 tune-up)
alanb
parents: 5995
diff changeset
   671
            /*
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   672
             * Check special cases.
6896
d229d56fd918 6976036: Dual-pivot quicksort update (10/2010 tune-up)
alanb
parents: 5995
diff changeset
   673
             */
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   674
            if (run == null) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   675
                if (k == high) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   676
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   677
                    /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   678
                     * The array is monotonous sequence,
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   679
                     * and therefore already sorted.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   680
                     */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   681
                    return true;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   682
                }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   683
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   684
                if (k - low < MIN_FIRST_RUN_SIZE) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   685
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   686
                    /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   687
                     * The first run is too small
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   688
                     * to proceed with scanning.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   689
                     */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   690
                    return false;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   691
                }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   692
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   693
                run = new int[((size >> 10) | 0x7F) & 0x3FF];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   694
                run[0] = low;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   695
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   696
            } else if (a[last - 1] > a[last]) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   697
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   698
                if (count > (k - low) >> MIN_FIRST_RUNS_FACTOR) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   699
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   700
                    /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   701
                     * The first runs are not long
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   702
                     * enough to continue scanning.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   703
                     */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   704
                    return false;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   705
                }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   706
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   707
                if (++count == MAX_RUN_CAPACITY) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   708
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   709
                    /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   710
                     * Array is not highly structured.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   711
                     */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   712
                    return false;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   713
                }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   714
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   715
                if (count == run.length) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   716
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   717
                    /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   718
                     * Increase capacity of index array.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   719
                     */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   720
                    run = Arrays.copyOf(run, count << 1);
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   721
                }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   722
            }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   723
            run[count] = (last = k);
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   724
        }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   725
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   726
        /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   727
         * Merge runs of highly structured array.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   728
         */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   729
        if (count > 1) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   730
            int[] b; int offset = low;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   731
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   732
            if (sorter == null || (b = (int[]) sorter.b) == null) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   733
                b = new int[size];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   734
            } else {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   735
                offset = sorter.offset;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   736
            }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   737
            mergeRuns(a, b, offset, 1, sorter != null, run, 0, count);
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   738
        }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   739
        return true;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   740
    }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   741
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   742
    /**
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   743
     * Merges the specified runs.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   744
     *
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   745
     * @param a the source array
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   746
     * @param b the temporary buffer used in merging
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   747
     * @param offset the start index in the source, inclusive
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   748
     * @param aim specifies merging: to source ( > 0), buffer ( < 0) or any ( == 0)
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   749
     * @param parallel indicates whether merging is performed in parallel
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   750
     * @param run the start indexes of the runs, inclusive
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   751
     * @param lo the start index of the first run, inclusive
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   752
     * @param hi the start index of the last run, inclusive
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   753
     * @return the destination where runs are merged
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   754
     */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   755
    private static int[] mergeRuns(int[] a, int[] b, int offset,
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   756
            int aim, boolean parallel, int[] run, int lo, int hi) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   757
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   758
        if (hi - lo == 1) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   759
            if (aim >= 0) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   760
                return a;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   761
            }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   762
            for (int i = run[hi], j = i - offset, low = run[lo]; i > low;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   763
                b[--j] = a[--i]
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   764
            );
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   765
            return b;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   766
        }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   767
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   768
        /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   769
         * Split into approximately equal parts.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   770
         */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   771
        int mi = lo, rmi = (run[lo] + run[hi]) >>> 1;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   772
        while (run[++mi + 1] <= rmi);
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   773
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   774
        /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   775
         * Merge the left and right parts.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   776
         */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   777
        int[] a1, a2;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   778
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   779
        if (parallel && hi - lo > MIN_RUN_COUNT) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   780
            RunMerger merger = new RunMerger(a, b, offset, 0, run, mi, hi).forkMe();
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   781
            a1 = mergeRuns(a, b, offset, -aim, true, run, lo, mi);
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   782
            a2 = (int[]) merger.getDestination();
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   783
        } else {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   784
            a1 = mergeRuns(a, b, offset, -aim, false, run, lo, mi);
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   785
            a2 = mergeRuns(a, b, offset,    0, false, run, mi, hi);
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   786
        }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   787
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   788
        int[] dst = a1 == a ? b : a;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   789
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   790
        int k   = a1 == a ? run[lo] - offset : run[lo];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   791
        int lo1 = a1 == b ? run[lo] - offset : run[lo];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   792
        int hi1 = a1 == b ? run[mi] - offset : run[mi];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   793
        int lo2 = a2 == b ? run[mi] - offset : run[mi];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   794
        int hi2 = a2 == b ? run[hi] - offset : run[hi];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   795
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   796
        if (parallel) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   797
            new Merger(null, dst, k, a1, lo1, hi1, a2, lo2, hi2).invoke();
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   798
        } else {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   799
            mergeParts(null, dst, k, a1, lo1, hi1, a2, lo2, hi2);
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   800
        }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   801
        return dst;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   802
    }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   803
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   804
    /**
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   805
     * Merges the sorted parts.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   806
     *
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   807
     * @param merger parallel context
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   808
     * @param dst the destination where parts are merged
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   809
     * @param k the start index of the destination, inclusive
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   810
     * @param a1 the first part
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   811
     * @param lo1 the start index of the first part, inclusive
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   812
     * @param hi1 the end index of the first part, exclusive
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   813
     * @param a2 the second part
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   814
     * @param lo2 the start index of the second part, inclusive
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   815
     * @param hi2 the end index of the second part, exclusive
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   816
     */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   817
    private static void mergeParts(Merger merger, int[] dst, int k,
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   818
            int[] a1, int lo1, int hi1, int[] a2, int lo2, int hi2) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   819
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   820
        if (merger != null && a1 == a2) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   821
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   822
            while (true) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   823
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   824
                /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   825
                 * The first part must be larger.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   826
                 */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   827
                if (hi1 - lo1 < hi2 - lo2) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   828
                    int lo = lo1; lo1 = lo2; lo2 = lo;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   829
                    int hi = hi1; hi1 = hi2; hi2 = hi;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   830
                }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   831
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   832
                /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   833
                 * Small parts will be merged sequentially.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   834
                 */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   835
                if (hi1 - lo1 < MIN_PARALLEL_MERGE_PARTS_SIZE) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   836
                    break;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   837
                }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   838
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   839
                /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   840
                 * Find the median of the larger part.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   841
                 */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   842
                int mi1 = (lo1 + hi1) >>> 1;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   843
                int key = a1[mi1];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   844
                int mi2 = hi2;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   845
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   846
                /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   847
                 * Partition the smaller part.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   848
                 */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   849
                for (int loo = lo2; loo < mi2; ) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   850
                    int t = (loo + mi2) >>> 1;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   851
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   852
                    if (key > a2[t]) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   853
                        loo = t + 1;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   854
                    } else {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   855
                        mi2 = t;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   856
                    }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   857
                }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   858
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   859
                int d = mi2 - lo2 + mi1 - lo1;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   860
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   861
                /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   862
                 * Merge the right sub-parts in parallel.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   863
                 */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   864
                merger.forkMerger(dst, k + d, a1, mi1, hi1, a2, mi2, hi2);
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   865
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   866
                /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   867
                 * Process the sub-left parts.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   868
                 */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   869
                hi1 = mi1;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   870
                hi2 = mi2;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   871
            }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   872
        }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   873
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   874
        /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   875
         * Merge small parts sequentially.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   876
         */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   877
        while (lo1 < hi1 && lo2 < hi2) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   878
            dst[k++] = a1[lo1] < a2[lo2] ? a1[lo1++] : a2[lo2++];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   879
        }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   880
        if (dst != a1 || k < lo1) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   881
            while (lo1 < hi1) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   882
                dst[k++] = a1[lo1++];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   883
            }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   884
        }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   885
        if (dst != a2 || k < lo2) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   886
            while (lo2 < hi2) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   887
                dst[k++] = a2[lo2++];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   888
            }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   889
        }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   890
    }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   891
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   892
// [long]
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   893
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   894
    /**
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   895
     * Sorts the specified range of the array using parallel merge
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   896
     * sort and/or Dual-Pivot Quicksort.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   897
     *
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   898
     * To balance the faster splitting and parallelism of merge sort
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   899
     * with the faster element partitioning of Quicksort, ranges are
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   900
     * subdivided in tiers such that, if there is enough parallelism,
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   901
     * the four-way parallel merge is started, still ensuring enough
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   902
     * parallelism to process the partitions.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   903
     *
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   904
     * @param a the array to be sorted
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   905
     * @param parallelism the parallelism level
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   906
     * @param low the index of the first element, inclusive, to be sorted
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   907
     * @param high the index of the last element, exclusive, to be sorted
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   908
     */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   909
    static void sort(long[] a, int parallelism, int low, int high) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   910
        int size = high - low;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   911
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   912
        if (parallelism > 1 && size > MIN_PARALLEL_SORT_SIZE) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   913
            int depth = getDepth(parallelism, size >> 12);
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   914
            long[] b = depth == 0 ? null : new long[size];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   915
            new Sorter(null, a, b, low, size, low, depth).invoke();
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   916
        } else {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   917
            sort(null, a, 0, low, high);
4170
a94a6faf44e6 6880672: Replace quicksort in java.util.Arrays with dual-pivot implementation
alanb
parents:
diff changeset
   918
        }
4233
9b594a48d0f4 6899694: Dual-pivot quicksort improvements
alanb
parents: 4177
diff changeset
   919
    }
9b594a48d0f4 6899694: Dual-pivot quicksort improvements
alanb
parents: 4177
diff changeset
   920
9b594a48d0f4 6899694: Dual-pivot quicksort improvements
alanb
parents: 4177
diff changeset
   921
    /**
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   922
     * Sorts the specified array using the Dual-Pivot Quicksort and/or
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   923
     * other sorts in special-cases, possibly with parallel partitions.
4233
9b594a48d0f4 6899694: Dual-pivot quicksort improvements
alanb
parents: 4177
diff changeset
   924
     *
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   925
     * @param sorter parallel context
8188
b90884cf34f5 7013585: Dual-pivot quicksort improvements for highly structured (nearly sorted) and data with small periods
alanb
parents: 6896
diff changeset
   926
     * @param a the array to be sorted
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   927
     * @param bits the combination of recursion depth and bit flag, where
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   928
     *        the right bit "0" indicates that array is the leftmost part
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   929
     * @param low the index of the first element, inclusive, to be sorted
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   930
     * @param high the index of the last element, exclusive, to be sorted
8188
b90884cf34f5 7013585: Dual-pivot quicksort improvements for highly structured (nearly sorted) and data with small periods
alanb
parents: 6896
diff changeset
   931
     */
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   932
    static void sort(Sorter sorter, long[] a, int bits, int low, int high) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   933
        while (true) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   934
            int end = high - 1, size = high - low;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   935
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   936
            /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   937
             * Run mixed insertion sort on small non-leftmost parts.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   938
             */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   939
            if (size < MAX_MIXED_INSERTION_SORT_SIZE + bits && (bits & 1) > 0) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   940
                mixedInsertionSort(a, low, high - 3 * ((size >> 5) << 3), high);
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   941
                return;
31079
bf5fabb914b6 8080945: Improve the performance of primitive Arrays.sort for certain patterns of array elements
psandoz
parents: 25859
diff changeset
   942
            }
bf5fabb914b6 8080945: Improve the performance of primitive Arrays.sort for certain patterns of array elements
psandoz
parents: 25859
diff changeset
   943
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   944
            /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   945
             * Invoke insertion sort on small leftmost part.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   946
             */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   947
            if (size < MAX_INSERTION_SORT_SIZE) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   948
                insertionSort(a, low, high);
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   949
                return;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   950
            }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   951
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   952
            /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   953
             * Check if the whole array or large non-leftmost
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   954
             * parts are nearly sorted and then merge runs.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   955
             */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   956
            if ((bits == 0 || size > MIN_TRY_MERGE_SIZE && (bits & 1) > 0)
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   957
                    && tryMergeRuns(sorter, a, low, size)) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   958
                return;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   959
            }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   960
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   961
            /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   962
             * Switch to heap sort if execution
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   963
             * time is becoming quadratic.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   964
             */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   965
            if ((bits += DELTA) > MAX_RECURSION_DEPTH) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   966
                heapSort(a, low, high);
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   967
                return;
8188
b90884cf34f5 7013585: Dual-pivot quicksort improvements for highly structured (nearly sorted) and data with small periods
alanb
parents: 6896
diff changeset
   968
            }
b90884cf34f5 7013585: Dual-pivot quicksort improvements for highly structured (nearly sorted) and data with small periods
alanb
parents: 6896
diff changeset
   969
b90884cf34f5 7013585: Dual-pivot quicksort improvements for highly structured (nearly sorted) and data with small periods
alanb
parents: 6896
diff changeset
   970
            /*
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   971
             * Use an inexpensive approximation of the golden ratio
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   972
             * to select five sample elements and determine pivots.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   973
             */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   974
            int step = (size >> 3) * 3 + 3;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   975
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   976
            /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   977
             * Five elements around (and including) the central element
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   978
             * will be used for pivot selection as described below. The
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   979
             * unequal choice of spacing these elements was empirically
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   980
             * determined to work well on a wide variety of inputs.
8188
b90884cf34f5 7013585: Dual-pivot quicksort improvements for highly structured (nearly sorted) and data with small periods
alanb
parents: 6896
diff changeset
   981
             */
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   982
            int e1 = low + step;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   983
            int e5 = end - step;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   984
            int e3 = (e1 + e5) >>> 1;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   985
            int e2 = (e1 + e3) >>> 1;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   986
            int e4 = (e3 + e5) >>> 1;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   987
            long a3 = a[e3];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   988
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   989
            /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   990
             * Sort these elements in place by the combination
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   991
             * of 4-element sorting network and insertion sort.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   992
             *
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   993
             *    5 ------o-----------o------------
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   994
             *            |           |
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   995
             *    4 ------|-----o-----o-----o------
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   996
             *            |     |           |
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   997
             *    2 ------o-----|-----o-----o------
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   998
             *                  |     |
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
   999
             *    1 ------------o-----o------------
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1000
             */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1001
            if (a[e5] < a[e2]) { long t = a[e5]; a[e5] = a[e2]; a[e2] = t; }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1002
            if (a[e4] < a[e1]) { long t = a[e4]; a[e4] = a[e1]; a[e1] = t; }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1003
            if (a[e5] < a[e4]) { long t = a[e5]; a[e5] = a[e4]; a[e4] = t; }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1004
            if (a[e2] < a[e1]) { long t = a[e2]; a[e2] = a[e1]; a[e1] = t; }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1005
            if (a[e4] < a[e2]) { long t = a[e4]; a[e4] = a[e2]; a[e2] = t; }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1006
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1007
            if (a3 < a[e2]) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1008
                if (a3 < a[e1]) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1009
                    a[e3] = a[e2]; a[e2] = a[e1]; a[e1] = a3;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1010
                } else {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1011
                    a[e3] = a[e2]; a[e2] = a3;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1012
                }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1013
            } else if (a3 > a[e4]) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1014
                if (a3 > a[e5]) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1015
                    a[e3] = a[e4]; a[e4] = a[e5]; a[e5] = a3;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1016
                } else {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1017
                    a[e3] = a[e4]; a[e4] = a3;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1018
                }
8188
b90884cf34f5 7013585: Dual-pivot quicksort improvements for highly structured (nearly sorted) and data with small periods
alanb
parents: 6896
diff changeset
  1019
            }
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1020
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1021
            // Pointers
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1022
            int lower = low; // The index of the last element of the left part
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1023
            int upper = end; // The index of the first element of the right part
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1024
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1025
            /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1026
             * Partitioning with 2 pivots in case of different elements.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1027
             */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1028
            if (a[e1] < a[e2] && a[e2] < a[e3] && a[e3] < a[e4] && a[e4] < a[e5]) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1029
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1030
                /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1031
                 * Use the first and fifth of the five sorted elements as
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1032
                 * the pivots. These values are inexpensive approximation
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1033
                 * of tertiles. Note, that pivot1 < pivot2.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1034
                 */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1035
                long pivot1 = a[e1];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1036
                long pivot2 = a[e5];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1037
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1038
                /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1039
                 * The first and the last elements to be sorted are moved
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1040
                 * to the locations formerly occupied by the pivots. When
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1041
                 * partitioning is completed, the pivots are swapped back
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1042
                 * into their final positions, and excluded from the next
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1043
                 * subsequent sorting.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1044
                 */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1045
                a[e1] = a[lower];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1046
                a[e5] = a[upper];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1047
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1048
                /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1049
                 * Skip elements, which are less or greater than the pivots.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1050
                 */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1051
                while (a[++lower] < pivot1);
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1052
                while (a[--upper] > pivot2);
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1053
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1054
                /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1055
                 * Backward 3-interval partitioning
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1056
                 *
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1057
                 *   left part                 central part          right part
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1058
                 * +------------------------------------------------------------+
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1059
                 * |  < pivot1  |   ?   |  pivot1 <= && <= pivot2  |  > pivot2  |
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1060
                 * +------------------------------------------------------------+
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1061
                 *             ^       ^                            ^
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1062
                 *             |       |                            |
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1063
                 *           lower     k                          upper
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1064
                 *
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1065
                 * Invariants:
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1066
                 *
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1067
                 *              all in (low, lower] < pivot1
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1068
                 *    pivot1 <= all in (k, upper)  <= pivot2
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1069
                 *              all in [upper, end) > pivot2
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1070
                 *
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1071
                 * Pointer k is the last index of ?-part
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1072
                 */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1073
                for (int unused = --lower, k = ++upper; --k > lower; ) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1074
                    long ak = a[k];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1075
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1076
                    if (ak < pivot1) { // Move a[k] to the left side
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1077
                        while (lower < k) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1078
                            if (a[++lower] >= pivot1) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1079
                                if (a[lower] > pivot2) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1080
                                    a[k] = a[--upper];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1081
                                    a[upper] = a[lower];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1082
                                } else {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1083
                                    a[k] = a[lower];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1084
                                }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1085
                                a[lower] = ak;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1086
                                break;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1087
                            }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1088
                        }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1089
                    } else if (ak > pivot2) { // Move a[k] to the right side
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1090
                        a[k] = a[--upper];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1091
                        a[upper] = ak;
8188
b90884cf34f5 7013585: Dual-pivot quicksort improvements for highly structured (nearly sorted) and data with small periods
alanb
parents: 6896
diff changeset
  1092
                    }
b90884cf34f5 7013585: Dual-pivot quicksort improvements for highly structured (nearly sorted) and data with small periods
alanb
parents: 6896
diff changeset
  1093
                }
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1094
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1095
                /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1096
                 * Swap the pivots into their final positions.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1097
                 */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1098
                a[low] = a[lower]; a[lower] = pivot1;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1099
                a[end] = a[upper]; a[upper] = pivot2;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1100
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1101
                /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1102
                 * Sort non-left parts recursively (possibly in parallel),
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1103
                 * excluding known pivots.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1104
                 */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1105
                if (size > MIN_PARALLEL_SORT_SIZE && sorter != null) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1106
                    sorter.forkSorter(bits | 1, lower + 1, upper);
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1107
                    sorter.forkSorter(bits | 1, upper + 1, high);
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1108
                } else {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1109
                    sort(sorter, a, bits | 1, lower + 1, upper);
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1110
                    sort(sorter, a, bits | 1, upper + 1, high);
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1111
                }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1112
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1113
            } else { // Use single pivot in case of many equal elements
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1114
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1115
                /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1116
                 * Use the third of the five sorted elements as the pivot.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1117
                 * This value is inexpensive approximation of the median.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1118
                 */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1119
                long pivot = a[e3];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1120
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1121
                /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1122
                 * The first element to be sorted is moved to the
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1123
                 * location formerly occupied by the pivot. After
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1124
                 * completion of partitioning the pivot is swapped
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1125
                 * back into its final position, and excluded from
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1126
                 * the next subsequent sorting.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1127
                 */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1128
                a[e3] = a[lower];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1129
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1130
                /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1131
                 * Traditional 3-way (Dutch National Flag) partitioning
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1132
                 *
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1133
                 *   left part                 central part    right part
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1134
                 * +------------------------------------------------------+
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1135
                 * |   < pivot   |     ?     |   == pivot   |   > pivot   |
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1136
                 * +------------------------------------------------------+
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1137
                 *              ^           ^                ^
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1138
                 *              |           |                |
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1139
                 *            lower         k              upper
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1140
                 *
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1141
                 * Invariants:
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1142
                 *
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1143
                 *   all in (low, lower] < pivot
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1144
                 *   all in (k, upper)  == pivot
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1145
                 *   all in [upper, end] > pivot
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1146
                 *
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1147
                 * Pointer k is the last index of ?-part
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1148
                 */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1149
                for (int k = ++upper; --k > lower; ) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1150
                    long ak = a[k];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1151
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1152
                    if (ak != pivot) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1153
                        a[k] = pivot;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1154
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1155
                        if (ak < pivot) { // Move a[k] to the left side
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1156
                            while (a[++lower] < pivot);
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1157
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1158
                            if (a[lower] > pivot) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1159
                                a[--upper] = a[lower];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1160
                            }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1161
                            a[lower] = ak;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1162
                        } else { // ak > pivot - Move a[k] to the right side
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1163
                            a[--upper] = ak;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1164
                        }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1165
                    }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1166
                }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1167
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1168
                /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1169
                 * Swap the pivot into its final position.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1170
                 */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1171
                a[low] = a[lower]; a[lower] = pivot;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1172
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1173
                /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1174
                 * Sort the right part (possibly in parallel), excluding
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1175
                 * known pivot. All elements from the central part are
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1176
                 * equal and therefore already sorted.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1177
                 */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1178
                if (size > MIN_PARALLEL_SORT_SIZE && sorter != null) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1179
                    sorter.forkSorter(bits | 1, upper, high);
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1180
                } else {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1181
                    sort(sorter, a, bits | 1, upper, high);
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1182
                }
8188
b90884cf34f5 7013585: Dual-pivot quicksort improvements for highly structured (nearly sorted) and data with small periods
alanb
parents: 6896
diff changeset
  1183
            }
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1184
            high = lower; // Iterate along the left part
8188
b90884cf34f5 7013585: Dual-pivot quicksort improvements for highly structured (nearly sorted) and data with small periods
alanb
parents: 6896
diff changeset
  1185
        }
b90884cf34f5 7013585: Dual-pivot quicksort improvements for highly structured (nearly sorted) and data with small periods
alanb
parents: 6896
diff changeset
  1186
    }
b90884cf34f5 7013585: Dual-pivot quicksort improvements for highly structured (nearly sorted) and data with small periods
alanb
parents: 6896
diff changeset
  1187
b90884cf34f5 7013585: Dual-pivot quicksort improvements for highly structured (nearly sorted) and data with small periods
alanb
parents: 6896
diff changeset
  1188
    /**
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1189
     * Sorts the specified range of the array using mixed insertion sort.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1190
     *
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1191
     * Mixed insertion sort is combination of simple insertion sort,
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1192
     * pin insertion sort and pair insertion sort.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1193
     *
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1194
     * In the context of Dual-Pivot Quicksort, the pivot element
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1195
     * from the left part plays the role of sentinel, because it
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1196
     * is less than any elements from the given part. Therefore,
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1197
     * expensive check of the left range can be skipped on each
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1198
     * iteration unless it is the leftmost call.
4170
a94a6faf44e6 6880672: Replace quicksort in java.util.Arrays with dual-pivot implementation
alanb
parents:
diff changeset
  1199
     *
a94a6faf44e6 6880672: Replace quicksort in java.util.Arrays with dual-pivot implementation
alanb
parents:
diff changeset
  1200
     * @param a the array to be sorted
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1201
     * @param low the index of the first element, inclusive, to be sorted
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1202
     * @param end the index of the last element for simple insertion sort
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1203
     * @param high the index of the last element, exclusive, to be sorted
5995
0b76e67c2054 6947216: Even more Dual-pivot quicksort improvements
alanb
parents: 5506
diff changeset
  1204
     */
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1205
    private static void mixedInsertionSort(long[] a, int low, int end, int high) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1206
        if (end == high) {
8188
b90884cf34f5 7013585: Dual-pivot quicksort improvements for highly structured (nearly sorted) and data with small periods
alanb
parents: 6896
diff changeset
  1207
5995
0b76e67c2054 6947216: Even more Dual-pivot quicksort improvements
alanb
parents: 5506
diff changeset
  1208
            /*
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1209
             * Invoke simple insertion sort on tiny array.
5995
0b76e67c2054 6947216: Even more Dual-pivot quicksort improvements
alanb
parents: 5506
diff changeset
  1210
             */
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1211
            for (int i; ++low < end; ) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1212
                long ai = a[i = low];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1213
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1214
                while (ai < a[--i]) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1215
                    a[i + 1] = a[i];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1216
                }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1217
                a[i + 1] = ai;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1218
            }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1219
        } else {
5995
0b76e67c2054 6947216: Even more Dual-pivot quicksort improvements
alanb
parents: 5506
diff changeset
  1220
4170
a94a6faf44e6 6880672: Replace quicksort in java.util.Arrays with dual-pivot implementation
alanb
parents:
diff changeset
  1221
            /*
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1222
             * Start with pin insertion sort on small part.
4170
a94a6faf44e6 6880672: Replace quicksort in java.util.Arrays with dual-pivot implementation
alanb
parents:
diff changeset
  1223
             *
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1224
             * Pin insertion sort is extended simple insertion sort.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1225
             * The main idea of this sort is to put elements larger
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1226
             * than an element called pin to the end of array (the
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1227
             * proper area for such elements). It avoids expensive
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1228
             * movements of these elements through the whole array.
5995
0b76e67c2054 6947216: Even more Dual-pivot quicksort improvements
alanb
parents: 5506
diff changeset
  1229
             */
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1230
            long pin = a[end];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1231
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1232
            for (int i, p = high; ++low < end; ) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1233
                long ai = a[i = low];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1234
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1235
                if (ai < a[i - 1]) { // Small element
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1236
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1237
                    /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1238
                     * Insert small element into sorted part.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1239
                     */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1240
                    a[i] = a[--i];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1241
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1242
                    while (ai < a[--i]) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1243
                        a[i + 1] = a[i];
4170
a94a6faf44e6 6880672: Replace quicksort in java.util.Arrays with dual-pivot implementation
alanb
parents:
diff changeset
  1244
                    }
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1245
                    a[i + 1] = ai;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1246
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1247
                } else if (p > i && ai > pin) { // Large element
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1248
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1249
                    /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1250
                     * Find element smaller than pin.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1251
                     */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1252
                    while (a[--p] > pin);
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1253
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1254
                    /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1255
                     * Swap it with large element.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1256
                     */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1257
                    if (p > i) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1258
                        ai = a[p];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1259
                        a[p] = a[i];
4170
a94a6faf44e6 6880672: Replace quicksort in java.util.Arrays with dual-pivot implementation
alanb
parents:
diff changeset
  1260
                    }
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1261
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1262
                    /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1263
                     * Insert small element into sorted part.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1264
                     */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1265
                    while (ai < a[--i]) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1266
                        a[i + 1] = a[i];
4170
a94a6faf44e6 6880672: Replace quicksort in java.util.Arrays with dual-pivot implementation
alanb
parents:
diff changeset
  1267
                    }
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1268
                    a[i + 1] = ai;
4170
a94a6faf44e6 6880672: Replace quicksort in java.util.Arrays with dual-pivot implementation
alanb
parents:
diff changeset
  1269
                }
a94a6faf44e6 6880672: Replace quicksort in java.util.Arrays with dual-pivot implementation
alanb
parents:
diff changeset
  1270
            }
4356
1f9c2400b8c5 6905046: More Dual-pivot quicksort improvements
jjb
parents: 4241
diff changeset
  1271
6896
d229d56fd918 6976036: Dual-pivot quicksort update (10/2010 tune-up)
alanb
parents: 5995
diff changeset
  1272
            /*
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1273
             * Continue with pair insertion sort on remain part.
6896
d229d56fd918 6976036: Dual-pivot quicksort update (10/2010 tune-up)
alanb
parents: 5995
diff changeset
  1274
             */
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1275
            for (int i; low < high; ++low) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1276
                long a1 = a[i = low], a2 = a[++low];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1277
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1278
                /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1279
                 * Insert two elements per iteration: at first, insert the
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1280
                 * larger element and then insert the smaller element, but
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1281
                 * from the position where the larger element was inserted.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1282
                 */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1283
                if (a1 > a2) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1284
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1285
                    while (a1 < a[--i]) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1286
                        a[i + 2] = a[i];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1287
                    }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1288
                    a[++i + 1] = a1;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1289
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1290
                    while (a2 < a[--i]) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1291
                        a[i + 1] = a[i];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1292
                    }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1293
                    a[i + 1] = a2;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1294
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1295
                } else if (a1 < a[i - 1]) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1296
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1297
                    while (a2 < a[--i]) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1298
                        a[i + 2] = a[i];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1299
                    }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1300
                    a[++i + 1] = a2;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1301
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1302
                    while (a1 < a[--i]) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1303
                        a[i + 1] = a[i];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1304
                    }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1305
                    a[i + 1] = a1;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1306
                }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1307
            }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1308
        }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1309
    }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1310
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1311
    /**
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1312
     * Sorts the specified range of the array using insertion sort.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1313
     *
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1314
     * @param a the array to be sorted
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1315
     * @param low the index of the first element, inclusive, to be sorted
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1316
     * @param high the index of the last element, exclusive, to be sorted
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1317
     */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1318
    private static void insertionSort(long[] a, int low, int high) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1319
        for (int i, k = low; ++k < high; ) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1320
            long ai = a[i = k];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1321
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1322
            if (ai < a[i - 1]) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1323
                while (--i >= low && ai < a[i]) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1324
                    a[i + 1] = a[i];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1325
                }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1326
                a[i + 1] = ai;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1327
            }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1328
        }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1329
    }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1330
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1331
    /**
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1332
     * Sorts the specified range of the array using heap sort.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1333
     *
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1334
     * @param a the array to be sorted
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1335
     * @param low the index of the first element, inclusive, to be sorted
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1336
     * @param high the index of the last element, exclusive, to be sorted
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1337
     */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1338
    private static void heapSort(long[] a, int low, int high) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1339
        for (int k = (low + high) >>> 1; k > low; ) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1340
            pushDown(a, --k, a[k], low, high);
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1341
        }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1342
        while (--high > low) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1343
            long max = a[low];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1344
            pushDown(a, low, a[high], low, high);
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1345
            a[high] = max;
4170
a94a6faf44e6 6880672: Replace quicksort in java.util.Arrays with dual-pivot implementation
alanb
parents:
diff changeset
  1346
        }
a94a6faf44e6 6880672: Replace quicksort in java.util.Arrays with dual-pivot implementation
alanb
parents:
diff changeset
  1347
    }
a94a6faf44e6 6880672: Replace quicksort in java.util.Arrays with dual-pivot implementation
alanb
parents:
diff changeset
  1348
a94a6faf44e6 6880672: Replace quicksort in java.util.Arrays with dual-pivot implementation
alanb
parents:
diff changeset
  1349
    /**
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1350
     * Pushes specified element down during heap sort.
4170
a94a6faf44e6 6880672: Replace quicksort in java.util.Arrays with dual-pivot implementation
alanb
parents:
diff changeset
  1351
     *
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1352
     * @param a the given array
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1353
     * @param p the start index
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1354
     * @param value the given element
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1355
     * @param low the index of the first element, inclusive, to be sorted
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1356
     * @param high the index of the last element, exclusive, to be sorted
4170
a94a6faf44e6 6880672: Replace quicksort in java.util.Arrays with dual-pivot implementation
alanb
parents:
diff changeset
  1357
     */
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1358
    private static void pushDown(long[] a, int p, long value, int low, int high) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1359
        for (int k ;; a[p] = a[p = k]) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1360
            k = (p << 1) - low + 2; // Index of the right child
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1361
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1362
            if (k > high) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1363
                break;
6896
d229d56fd918 6976036: Dual-pivot quicksort update (10/2010 tune-up)
alanb
parents: 5995
diff changeset
  1364
            }
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1365
            if (k == high || a[k] < a[k - 1]) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1366
                --k;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1367
            }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1368
            if (a[k] <= value) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1369
                break;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1370
            }
5995
0b76e67c2054 6947216: Even more Dual-pivot quicksort improvements
alanb
parents: 5506
diff changeset
  1371
        }
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1372
        a[p] = value;
4170
a94a6faf44e6 6880672: Replace quicksort in java.util.Arrays with dual-pivot implementation
alanb
parents:
diff changeset
  1373
    }
a94a6faf44e6 6880672: Replace quicksort in java.util.Arrays with dual-pivot implementation
alanb
parents:
diff changeset
  1374
a94a6faf44e6 6880672: Replace quicksort in java.util.Arrays with dual-pivot implementation
alanb
parents:
diff changeset
  1375
    /**
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1376
     * Tries to sort the specified range of the array.
8188
b90884cf34f5 7013585: Dual-pivot quicksort improvements for highly structured (nearly sorted) and data with small periods
alanb
parents: 6896
diff changeset
  1377
     *
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1378
     * @param sorter parallel context
8188
b90884cf34f5 7013585: Dual-pivot quicksort improvements for highly structured (nearly sorted) and data with small periods
alanb
parents: 6896
diff changeset
  1379
     * @param a the array to be sorted
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1380
     * @param low the index of the first element to be sorted
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1381
     * @param size the array size
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1382
     * @return true if finally sorted, false otherwise
8188
b90884cf34f5 7013585: Dual-pivot quicksort improvements for highly structured (nearly sorted) and data with small periods
alanb
parents: 6896
diff changeset
  1383
     */
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1384
    private static boolean tryMergeRuns(Sorter sorter, long[] a, int low, int size) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1385
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1386
        /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1387
         * The run array is constructed only if initial runs are
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1388
         * long enough to continue, run[i] then holds start index
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1389
         * of the i-th sequence of elements in non-descending order.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1390
         */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1391
        int[] run = null;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1392
        int high = low + size;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1393
        int count = 1, last = low;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1394
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1395
        /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1396
         * Identify all possible runs.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1397
         */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1398
        for (int k = low + 1; k < high; ) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1399
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1400
            /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1401
             * Find the end index of the current run.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1402
             */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1403
            if (a[k - 1] < a[k]) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1404
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1405
                // Identify ascending sequence
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1406
                while (++k < high && a[k - 1] <= a[k]);
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1407
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1408
            } else if (a[k - 1] > a[k]) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1409
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1410
                // Identify descending sequence
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1411
                while (++k < high && a[k - 1] >= a[k]);
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1412
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1413
                // Reverse into ascending order
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1414
                for (int i = last - 1, j = k; ++i < --j && a[i] > a[j]; ) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1415
                    long ai = a[i]; a[i] = a[j]; a[j] = ai;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1416
                }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1417
            } else { // Identify constant sequence
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1418
                for (long ak = a[k]; ++k < high && ak == a[k]; );
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1419
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1420
                if (k < high) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1421
                    continue;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1422
                }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1423
            }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1424
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1425
            /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1426
             * Check special cases.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1427
             */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1428
            if (run == null) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1429
                if (k == high) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1430
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1431
                    /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1432
                     * The array is monotonous sequence,
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1433
                     * and therefore already sorted.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1434
                     */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1435
                    return true;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1436
                }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1437
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1438
                if (k - low < MIN_FIRST_RUN_SIZE) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1439
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1440
                    /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1441
                     * The first run is too small
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1442
                     * to proceed with scanning.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1443
                     */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1444
                    return false;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1445
                }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1446
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1447
                run = new int[((size >> 10) | 0x7F) & 0x3FF];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1448
                run[0] = low;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1449
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1450
            } else if (a[last - 1] > a[last]) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1451
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1452
                if (count > (k - low) >> MIN_FIRST_RUNS_FACTOR) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1453
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1454
                    /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1455
                     * The first runs are not long
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1456
                     * enough to continue scanning.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1457
                     */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1458
                    return false;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1459
                }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1460
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1461
                if (++count == MAX_RUN_CAPACITY) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1462
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1463
                    /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1464
                     * Array is not highly structured.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1465
                     */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1466
                    return false;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1467
                }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1468
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1469
                if (count == run.length) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1470
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1471
                    /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1472
                     * Increase capacity of index array.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1473
                     */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1474
                    run = Arrays.copyOf(run, count << 1);
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1475
                }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1476
            }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1477
            run[count] = (last = k);
8188
b90884cf34f5 7013585: Dual-pivot quicksort improvements for highly structured (nearly sorted) and data with small periods
alanb
parents: 6896
diff changeset
  1478
        }
b90884cf34f5 7013585: Dual-pivot quicksort improvements for highly structured (nearly sorted) and data with small periods
alanb
parents: 6896
diff changeset
  1479
b90884cf34f5 7013585: Dual-pivot quicksort improvements for highly structured (nearly sorted) and data with small periods
alanb
parents: 6896
diff changeset
  1480
        /*
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1481
         * Merge runs of highly structured array.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1482
         */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1483
        if (count > 1) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1484
            long[] b; int offset = low;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1485
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1486
            if (sorter == null || (b = (long[]) sorter.b) == null) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1487
                b = new long[size];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1488
            } else {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1489
                offset = sorter.offset;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1490
            }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1491
            mergeRuns(a, b, offset, 1, sorter != null, run, 0, count);
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1492
        }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1493
        return true;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1494
    }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1495
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1496
    /**
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1497
     * Merges the specified runs.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1498
     *
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1499
     * @param a the source array
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1500
     * @param b the temporary buffer used in merging
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1501
     * @param offset the start index in the source, inclusive
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1502
     * @param aim specifies merging: to source ( > 0), buffer ( < 0) or any ( == 0)
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1503
     * @param parallel indicates whether merging is performed in parallel
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1504
     * @param run the start indexes of the runs, inclusive
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1505
     * @param lo the start index of the first run, inclusive
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1506
     * @param hi the start index of the last run, inclusive
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1507
     * @return the destination where runs are merged
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1508
     */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1509
    private static long[] mergeRuns(long[] a, long[] b, int offset,
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1510
            int aim, boolean parallel, int[] run, int lo, int hi) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1511
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1512
        if (hi - lo == 1) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1513
            if (aim >= 0) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1514
                return a;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1515
            }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1516
            for (int i = run[hi], j = i - offset, low = run[lo]; i > low;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1517
                b[--j] = a[--i]
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1518
            );
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1519
            return b;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1520
        }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1521
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1522
        /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1523
         * Split into approximately equal parts.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1524
         */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1525
        int mi = lo, rmi = (run[lo] + run[hi]) >>> 1;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1526
        while (run[++mi + 1] <= rmi);
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1527
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1528
        /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1529
         * Merge the left and right parts.
8188
b90884cf34f5 7013585: Dual-pivot quicksort improvements for highly structured (nearly sorted) and data with small periods
alanb
parents: 6896
diff changeset
  1530
         */
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1531
        long[] a1, a2;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1532
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1533
        if (parallel && hi - lo > MIN_RUN_COUNT) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1534
            RunMerger merger = new RunMerger(a, b, offset, 0, run, mi, hi).forkMe();
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1535
            a1 = mergeRuns(a, b, offset, -aim, true, run, lo, mi);
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1536
            a2 = (long[]) merger.getDestination();
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1537
        } else {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1538
            a1 = mergeRuns(a, b, offset, -aim, false, run, lo, mi);
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1539
            a2 = mergeRuns(a, b, offset,    0, false, run, mi, hi);
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1540
        }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1541
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1542
        long[] dst = a1 == a ? b : a;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1543
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1544
        int k   = a1 == a ? run[lo] - offset : run[lo];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1545
        int lo1 = a1 == b ? run[lo] - offset : run[lo];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1546
        int hi1 = a1 == b ? run[mi] - offset : run[mi];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1547
        int lo2 = a2 == b ? run[mi] - offset : run[mi];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1548
        int hi2 = a2 == b ? run[hi] - offset : run[hi];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1549
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1550
        if (parallel) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1551
            new Merger(null, dst, k, a1, lo1, hi1, a2, lo2, hi2).invoke();
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1552
        } else {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1553
            mergeParts(null, dst, k, a1, lo1, hi1, a2, lo2, hi2);
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1554
        }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1555
        return dst;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1556
    }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1557
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1558
    /**
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1559
     * Merges the sorted parts.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1560
     *
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1561
     * @param merger parallel context
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1562
     * @param dst the destination where parts are merged
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1563
     * @param k the start index of the destination, inclusive
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1564
     * @param a1 the first part
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1565
     * @param lo1 the start index of the first part, inclusive
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1566
     * @param hi1 the end index of the first part, exclusive
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1567
     * @param a2 the second part
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1568
     * @param lo2 the start index of the second part, inclusive
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1569
     * @param hi2 the end index of the second part, exclusive
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1570
     */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1571
    private static void mergeParts(Merger merger, long[] dst, int k,
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1572
            long[] a1, int lo1, int hi1, long[] a2, int lo2, int hi2) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1573
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1574
        if (merger != null && a1 == a2) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1575
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1576
            while (true) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1577
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1578
                /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1579
                 * The first part must be larger.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1580
                 */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1581
                if (hi1 - lo1 < hi2 - lo2) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1582
                    int lo = lo1; lo1 = lo2; lo2 = lo;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1583
                    int hi = hi1; hi1 = hi2; hi2 = hi;
8188
b90884cf34f5 7013585: Dual-pivot quicksort improvements for highly structured (nearly sorted) and data with small periods
alanb
parents: 6896
diff changeset
  1584
                }
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1585
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1586
                /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1587
                 * Small parts will be merged sequentially.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1588
                 */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1589
                if (hi1 - lo1 < MIN_PARALLEL_MERGE_PARTS_SIZE) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1590
                    break;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1591
                }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1592
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1593
                /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1594
                 * Find the median of the larger part.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1595
                 */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1596
                int mi1 = (lo1 + hi1) >>> 1;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1597
                long key = a1[mi1];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1598
                int mi2 = hi2;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1599
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1600
                /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1601
                 * Partition the smaller part.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1602
                 */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1603
                for (int loo = lo2; loo < mi2; ) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1604
                    int t = (loo + mi2) >>> 1;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1605
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1606
                    if (key > a2[t]) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1607
                        loo = t + 1;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1608
                    } else {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1609
                        mi2 = t;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1610
                    }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1611
                }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1612
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1613
                int d = mi2 - lo2 + mi1 - lo1;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1614
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1615
                /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1616
                 * Merge the right sub-parts in parallel.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1617
                 */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1618
                merger.forkMerger(dst, k + d, a1, mi1, hi1, a2, mi2, hi2);
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1619
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1620
                /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1621
                 * Process the sub-left parts.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1622
                 */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1623
                hi1 = mi1;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1624
                hi2 = mi2;
8188
b90884cf34f5 7013585: Dual-pivot quicksort improvements for highly structured (nearly sorted) and data with small periods
alanb
parents: 6896
diff changeset
  1625
            }
b90884cf34f5 7013585: Dual-pivot quicksort improvements for highly structured (nearly sorted) and data with small periods
alanb
parents: 6896
diff changeset
  1626
        }
b90884cf34f5 7013585: Dual-pivot quicksort improvements for highly structured (nearly sorted) and data with small periods
alanb
parents: 6896
diff changeset
  1627
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1628
        /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1629
         * Merge small parts sequentially.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1630
         */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1631
        while (lo1 < hi1 && lo2 < hi2) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1632
            dst[k++] = a1[lo1] < a2[lo2] ? a1[lo1++] : a2[lo2++];
37912
80b046f15b53 8154049: DualPivot sorting calculates incorrect runs for nearly sorted arrays
psandoz
parents: 31079
diff changeset
  1633
        }
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1634
        if (dst != a1 || k < lo1) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1635
            while (lo1 < hi1) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1636
                dst[k++] = a1[lo1++];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1637
            }
8188
b90884cf34f5 7013585: Dual-pivot quicksort improvements for highly structured (nearly sorted) and data with small periods
alanb
parents: 6896
diff changeset
  1638
        }
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1639
        if (dst != a2 || k < lo2) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1640
            while (lo2 < hi2) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1641
                dst[k++] = a2[lo2++];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1642
            }
17712
b56c69500af6 8014076: Arrays parallel and serial sorting improvements
dl
parents: 9035
diff changeset
  1643
        }
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1644
    }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1645
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1646
// [byte]
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1647
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1648
    /**
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1649
     * Sorts the specified range of the array using
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1650
     * counting sort or insertion sort.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1651
     *
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1652
     * @param a the array to be sorted
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1653
     * @param low the index of the first element, inclusive, to be sorted
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1654
     * @param high the index of the last element, exclusive, to be sorted
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1655
     */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1656
    static void sort(byte[] a, int low, int high) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1657
        if (high - low > MIN_BYTE_COUNTING_SORT_SIZE) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1658
            countingSort(a, low, high);
8188
b90884cf34f5 7013585: Dual-pivot quicksort improvements for highly structured (nearly sorted) and data with small periods
alanb
parents: 6896
diff changeset
  1659
        } else {
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1660
            insertionSort(a, low, high);
8188
b90884cf34f5 7013585: Dual-pivot quicksort improvements for highly structured (nearly sorted) and data with small periods
alanb
parents: 6896
diff changeset
  1661
        }
b90884cf34f5 7013585: Dual-pivot quicksort improvements for highly structured (nearly sorted) and data with small periods
alanb
parents: 6896
diff changeset
  1662
    }
b90884cf34f5 7013585: Dual-pivot quicksort improvements for highly structured (nearly sorted) and data with small periods
alanb
parents: 6896
diff changeset
  1663
b90884cf34f5 7013585: Dual-pivot quicksort improvements for highly structured (nearly sorted) and data with small periods
alanb
parents: 6896
diff changeset
  1664
    /**
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1665
     * Sorts the specified range of the array using insertion sort.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1666
     *
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1667
     * @param a the array to be sorted
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1668
     * @param low the index of the first element, inclusive, to be sorted
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1669
     * @param high the index of the last element, exclusive, to be sorted
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1670
     */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1671
    private static void insertionSort(byte[] a, int low, int high) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1672
        for (int i, k = low; ++k < high; ) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1673
            byte ai = a[i = k];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1674
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1675
            if (ai < a[i - 1]) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1676
                while (--i >= low && ai < a[i]) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1677
                    a[i + 1] = a[i];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1678
                }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1679
                a[i + 1] = ai;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1680
            }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1681
        }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1682
    }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1683
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1684
    /**
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1685
     * The number of distinct byte values.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1686
     */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1687
    private static final int NUM_BYTE_VALUES = 1 << 8;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1688
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1689
    /**
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1690
     * Max index of byte counter.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1691
     */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1692
    private static final int MAX_BYTE_INDEX = Byte.MAX_VALUE + NUM_BYTE_VALUES + 1;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1693
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1694
    /**
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1695
     * Sorts the specified range of the array using counting sort.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1696
     *
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1697
     * @param a the array to be sorted
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1698
     * @param low the index of the first element, inclusive, to be sorted
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1699
     * @param high the index of the last element, exclusive, to be sorted
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1700
     */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1701
    private static void countingSort(byte[] a, int low, int high) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1702
        int[] count = new int[NUM_BYTE_VALUES];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1703
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1704
        /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1705
         * Compute a histogram with the number of each values.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1706
         */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1707
        for (int i = high; i > low; ++count[a[--i] & 0xFF]);
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1708
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1709
        /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1710
         * Place values on their final positions.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1711
         */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1712
        if (high - low > NUM_BYTE_VALUES) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1713
            for (int i = MAX_BYTE_INDEX; --i > Byte.MAX_VALUE; ) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1714
                int value = i & 0xFF;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1715
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1716
                for (low = high - count[value]; high > low;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1717
                    a[--high] = (byte) value
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1718
                );
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1719
            }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1720
        } else {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1721
            for (int i = MAX_BYTE_INDEX; high > low; ) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1722
                while (count[--i & 0xFF] == 0);
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1723
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1724
                int value = i & 0xFF;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1725
                int c = count[value];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1726
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1727
                do {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1728
                    a[--high] = (byte) value;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1729
                } while (--c > 0);
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1730
            }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1731
        }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1732
    }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1733
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1734
// [char]
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1735
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1736
    /**
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1737
     * Sorts the specified range of the array using
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1738
     * counting sort or Dual-Pivot Quicksort.
4170
a94a6faf44e6 6880672: Replace quicksort in java.util.Arrays with dual-pivot implementation
alanb
parents:
diff changeset
  1739
     *
a94a6faf44e6 6880672: Replace quicksort in java.util.Arrays with dual-pivot implementation
alanb
parents:
diff changeset
  1740
     * @param a the array to be sorted
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1741
     * @param low the index of the first element, inclusive, to be sorted
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1742
     * @param high the index of the last element, exclusive, to be sorted
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1743
     */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1744
    static void sort(char[] a, int low, int high) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1745
        if (high - low > MIN_SHORT_OR_CHAR_COUNTING_SORT_SIZE) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1746
            countingSort(a, low, high);
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1747
        } else {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1748
            sort(a, 0, low, high);
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1749
        }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1750
    }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1751
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1752
    /**
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1753
     * Sorts the specified array using the Dual-Pivot Quicksort and/or
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1754
     * other sorts in special-cases, possibly with parallel partitions.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1755
     *
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1756
     * @param a the array to be sorted
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1757
     * @param bits the combination of recursion depth and bit flag, where
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1758
     *        the right bit "0" indicates that array is the leftmost part
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1759
     * @param low the index of the first element, inclusive, to be sorted
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1760
     * @param high the index of the last element, exclusive, to be sorted
5995
0b76e67c2054 6947216: Even more Dual-pivot quicksort improvements
alanb
parents: 5506
diff changeset
  1761
     */
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1762
    static void sort(char[] a, int bits, int low, int high) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1763
        while (true) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1764
            int end = high - 1, size = high - low;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1765
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1766
            /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1767
             * Invoke insertion sort on small leftmost part.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1768
             */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1769
            if (size < MAX_INSERTION_SORT_SIZE) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1770
                insertionSort(a, low, high);
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1771
                return;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1772
            }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1773
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1774
            /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1775
             * Switch to counting sort if execution
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1776
             * time is becoming quadratic.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1777
             */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1778
            if ((bits += DELTA) > MAX_RECURSION_DEPTH) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1779
                countingSort(a, low, high);
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1780
                return;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1781
            }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1782
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1783
            /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1784
             * Use an inexpensive approximation of the golden ratio
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1785
             * to select five sample elements and determine pivots.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1786
             */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1787
            int step = (size >> 3) * 3 + 3;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1788
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1789
            /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1790
             * Five elements around (and including) the central element
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1791
             * will be used for pivot selection as described below. The
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1792
             * unequal choice of spacing these elements was empirically
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1793
             * determined to work well on a wide variety of inputs.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1794
             */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1795
            int e1 = low + step;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1796
            int e5 = end - step;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1797
            int e3 = (e1 + e5) >>> 1;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1798
            int e2 = (e1 + e3) >>> 1;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1799
            int e4 = (e3 + e5) >>> 1;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1800
            char a3 = a[e3];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1801
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1802
            /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1803
             * Sort these elements in place by the combination
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1804
             * of 4-element sorting network and insertion sort.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1805
             *
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1806
             *    5 ------o-----------o------------
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1807
             *            |           |
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1808
             *    4 ------|-----o-----o-----o------
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1809
             *            |     |           |
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1810
             *    2 ------o-----|-----o-----o------
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1811
             *                  |     |
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1812
             *    1 ------------o-----o------------
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1813
             */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1814
            if (a[e5] < a[e2]) { char t = a[e5]; a[e5] = a[e2]; a[e2] = t; }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1815
            if (a[e4] < a[e1]) { char t = a[e4]; a[e4] = a[e1]; a[e1] = t; }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1816
            if (a[e5] < a[e4]) { char t = a[e5]; a[e5] = a[e4]; a[e4] = t; }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1817
            if (a[e2] < a[e1]) { char t = a[e2]; a[e2] = a[e1]; a[e1] = t; }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1818
            if (a[e4] < a[e2]) { char t = a[e4]; a[e4] = a[e2]; a[e2] = t; }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1819
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1820
            if (a3 < a[e2]) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1821
                if (a3 < a[e1]) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1822
                    a[e3] = a[e2]; a[e2] = a[e1]; a[e1] = a3;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1823
                } else {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1824
                    a[e3] = a[e2]; a[e2] = a3;
5995
0b76e67c2054 6947216: Even more Dual-pivot quicksort improvements
alanb
parents: 5506
diff changeset
  1825
                }
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1826
            } else if (a3 > a[e4]) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1827
                if (a3 > a[e5]) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1828
                    a[e3] = a[e4]; a[e4] = a[e5]; a[e5] = a3;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1829
                } else {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1830
                    a[e3] = a[e4]; a[e4] = a3;
5995
0b76e67c2054 6947216: Even more Dual-pivot quicksort improvements
alanb
parents: 5506
diff changeset
  1831
                }
0b76e67c2054 6947216: Even more Dual-pivot quicksort improvements
alanb
parents: 5506
diff changeset
  1832
            }
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1833
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1834
            // Pointers
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1835
            int lower = low; // The index of the last element of the left part
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1836
            int upper = end; // The index of the first element of the right part
5995
0b76e67c2054 6947216: Even more Dual-pivot quicksort improvements
alanb
parents: 5506
diff changeset
  1837
4170
a94a6faf44e6 6880672: Replace quicksort in java.util.Arrays with dual-pivot implementation
alanb
parents:
diff changeset
  1838
            /*
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1839
             * Partitioning with 2 pivots in case of different elements.
4170
a94a6faf44e6 6880672: Replace quicksort in java.util.Arrays with dual-pivot implementation
alanb
parents:
diff changeset
  1840
             */
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1841
            if (a[e1] < a[e2] && a[e2] < a[e3] && a[e3] < a[e4] && a[e4] < a[e5]) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1842
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1843
                /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1844
                 * Use the first and fifth of the five sorted elements as
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1845
                 * the pivots. These values are inexpensive approximation
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1846
                 * of tertiles. Note, that pivot1 < pivot2.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1847
                 */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1848
                char pivot1 = a[e1];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1849
                char pivot2 = a[e5];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1850
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1851
                /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1852
                 * The first and the last elements to be sorted are moved
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1853
                 * to the locations formerly occupied by the pivots. When
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1854
                 * partitioning is completed, the pivots are swapped back
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1855
                 * into their final positions, and excluded from the next
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1856
                 * subsequent sorting.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1857
                 */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1858
                a[e1] = a[lower];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1859
                a[e5] = a[upper];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1860
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1861
                /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1862
                 * Skip elements, which are less or greater than the pivots.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1863
                 */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1864
                while (a[++lower] < pivot1);
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1865
                while (a[--upper] > pivot2);
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1866
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1867
                /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1868
                 * Backward 3-interval partitioning
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1869
                 *
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1870
                 *   left part                 central part          right part
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1871
                 * +------------------------------------------------------------+
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1872
                 * |  < pivot1  |   ?   |  pivot1 <= && <= pivot2  |  > pivot2  |
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1873
                 * +------------------------------------------------------------+
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1874
                 *             ^       ^                            ^
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1875
                 *             |       |                            |
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1876
                 *           lower     k                          upper
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1877
                 *
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1878
                 * Invariants:
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1879
                 *
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1880
                 *              all in (low, lower] < pivot1
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1881
                 *    pivot1 <= all in (k, upper)  <= pivot2
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1882
                 *              all in [upper, end) > pivot2
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1883
                 *
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1884
                 * Pointer k is the last index of ?-part
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1885
                 */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1886
                for (int unused = --lower, k = ++upper; --k > lower; ) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1887
                    char ak = a[k];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1888
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1889
                    if (ak < pivot1) { // Move a[k] to the left side
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1890
                        while (lower < k) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1891
                            if (a[++lower] >= pivot1) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1892
                                if (a[lower] > pivot2) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1893
                                    a[k] = a[--upper];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1894
                                    a[upper] = a[lower];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1895
                                } else {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1896
                                    a[k] = a[lower];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1897
                                }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1898
                                a[lower] = ak;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1899
                                break;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1900
                            }
4241
7d4f50f3806c 6901318: Yet more Dual-pivot quicksort improvements
alanb
parents: 4233
diff changeset
  1901
                        }
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1902
                    } else if (ak > pivot2) { // Move a[k] to the right side
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1903
                        a[k] = a[--upper];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1904
                        a[upper] = ak;
4170
a94a6faf44e6 6880672: Replace quicksort in java.util.Arrays with dual-pivot implementation
alanb
parents:
diff changeset
  1905
                    }
5995
0b76e67c2054 6947216: Even more Dual-pivot quicksort improvements
alanb
parents: 5506
diff changeset
  1906
                }
0b76e67c2054 6947216: Even more Dual-pivot quicksort improvements
alanb
parents: 5506
diff changeset
  1907
0b76e67c2054 6947216: Even more Dual-pivot quicksort improvements
alanb
parents: 5506
diff changeset
  1908
                /*
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1909
                 * Swap the pivots into their final positions.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1910
                 */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1911
                a[low] = a[lower]; a[lower] = pivot1;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1912
                a[end] = a[upper]; a[upper] = pivot2;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1913
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1914
                /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1915
                 * Sort non-left parts recursively,
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1916
                 * excluding known pivots.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1917
                 */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1918
                sort(a, bits | 1, lower + 1, upper);
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1919
                sort(a, bits | 1, upper + 1, high);
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1920
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1921
            } else { // Use single pivot in case of many equal elements
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1922
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1923
                /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1924
                 * Use the third of the five sorted elements as the pivot.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1925
                 * This value is inexpensive approximation of the median.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1926
                 */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1927
                char pivot = a[e3];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1928
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1929
                /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1930
                 * The first element to be sorted is moved to the
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1931
                 * location formerly occupied by the pivot. After
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1932
                 * completion of partitioning the pivot is swapped
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1933
                 * back into its final position, and excluded from
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1934
                 * the next subsequent sorting.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1935
                 */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1936
                a[e3] = a[lower];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1937
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1938
                /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1939
                 * Traditional 3-way (Dutch National Flag) partitioning
5995
0b76e67c2054 6947216: Even more Dual-pivot quicksort improvements
alanb
parents: 5506
diff changeset
  1940
                 *
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1941
                 *   left part                 central part    right part
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1942
                 * +------------------------------------------------------+
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1943
                 * |   < pivot   |     ?     |   == pivot   |   > pivot   |
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1944
                 * +------------------------------------------------------+
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1945
                 *              ^           ^                ^
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1946
                 *              |           |                |
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1947
                 *            lower         k              upper
5995
0b76e67c2054 6947216: Even more Dual-pivot quicksort improvements
alanb
parents: 5506
diff changeset
  1948
                 *
0b76e67c2054 6947216: Even more Dual-pivot quicksort improvements
alanb
parents: 5506
diff changeset
  1949
                 * Invariants:
0b76e67c2054 6947216: Even more Dual-pivot quicksort improvements
alanb
parents: 5506
diff changeset
  1950
                 *
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1951
                 *   all in (low, lower] < pivot
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1952
                 *   all in (k, upper)  == pivot
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1953
                 *   all in [upper, end] > pivot
5995
0b76e67c2054 6947216: Even more Dual-pivot quicksort improvements
alanb
parents: 5506
diff changeset
  1954
                 *
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1955
                 * Pointer k is the last index of ?-part
5995
0b76e67c2054 6947216: Even more Dual-pivot quicksort improvements
alanb
parents: 5506
diff changeset
  1956
                 */
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1957
                for (int k = ++upper; --k > lower; ) {
5995
0b76e67c2054 6947216: Even more Dual-pivot quicksort improvements
alanb
parents: 5506
diff changeset
  1958
                    char ak = a[k];
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1959
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1960
                    if (ak != pivot) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1961
                        a[k] = pivot;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1962
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1963
                        if (ak < pivot) { // Move a[k] to the left side
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1964
                            while (a[++lower] < pivot);
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1965
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1966
                            if (a[lower] > pivot) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1967
                                a[--upper] = a[lower];
5995
0b76e67c2054 6947216: Even more Dual-pivot quicksort improvements
alanb
parents: 5506
diff changeset
  1968
                            }
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1969
                            a[lower] = ak;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1970
                        } else { // ak > pivot - Move a[k] to the right side
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1971
                            a[--upper] = ak;
5995
0b76e67c2054 6947216: Even more Dual-pivot quicksort improvements
alanb
parents: 5506
diff changeset
  1972
                        }
4170
a94a6faf44e6 6880672: Replace quicksort in java.util.Arrays with dual-pivot implementation
alanb
parents:
diff changeset
  1973
                    }
a94a6faf44e6 6880672: Replace quicksort in java.util.Arrays with dual-pivot implementation
alanb
parents:
diff changeset
  1974
                }
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1975
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1976
                /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1977
                 * Swap the pivot into its final position.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1978
                 */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1979
                a[low] = a[lower]; a[lower] = pivot;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1980
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1981
                /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1982
                 * Sort the right part, excluding known pivot.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1983
                 * All elements from the central part are
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1984
                 * equal and therefore already sorted.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1985
                 */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1986
                sort(a, bits | 1, upper, high);
4170
a94a6faf44e6 6880672: Replace quicksort in java.util.Arrays with dual-pivot implementation
alanb
parents:
diff changeset
  1987
            }
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1988
            high = lower; // Iterate along the left part
4170
a94a6faf44e6 6880672: Replace quicksort in java.util.Arrays with dual-pivot implementation
alanb
parents:
diff changeset
  1989
        }
4233
9b594a48d0f4 6899694: Dual-pivot quicksort improvements
alanb
parents: 4177
diff changeset
  1990
    }
9b594a48d0f4 6899694: Dual-pivot quicksort improvements
alanb
parents: 4177
diff changeset
  1991
9b594a48d0f4 6899694: Dual-pivot quicksort improvements
alanb
parents: 4177
diff changeset
  1992
    /**
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1993
     * Sorts the specified range of the array using insertion sort.
4170
a94a6faf44e6 6880672: Replace quicksort in java.util.Arrays with dual-pivot implementation
alanb
parents:
diff changeset
  1994
     *
a94a6faf44e6 6880672: Replace quicksort in java.util.Arrays with dual-pivot implementation
alanb
parents:
diff changeset
  1995
     * @param a the array to be sorted
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1996
     * @param low the index of the first element, inclusive, to be sorted
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1997
     * @param high the index of the last element, exclusive, to be sorted
4170
a94a6faf44e6 6880672: Replace quicksort in java.util.Arrays with dual-pivot implementation
alanb
parents:
diff changeset
  1998
     */
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  1999
    private static void insertionSort(char[] a, int low, int high) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2000
        for (int i, k = low; ++k < high; ) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2001
            char ai = a[i = k];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2002
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2003
            if (ai < a[i - 1]) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2004
                while (--i >= low && ai < a[i]) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2005
                    a[i + 1] = a[i];
6896
d229d56fd918 6976036: Dual-pivot quicksort update (10/2010 tune-up)
alanb
parents: 5995
diff changeset
  2006
                }
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2007
                a[i + 1] = ai;
6896
d229d56fd918 6976036: Dual-pivot quicksort update (10/2010 tune-up)
alanb
parents: 5995
diff changeset
  2008
            }
5995
0b76e67c2054 6947216: Even more Dual-pivot quicksort improvements
alanb
parents: 5506
diff changeset
  2009
        }
0b76e67c2054 6947216: Even more Dual-pivot quicksort improvements
alanb
parents: 5506
diff changeset
  2010
    }
0b76e67c2054 6947216: Even more Dual-pivot quicksort improvements
alanb
parents: 5506
diff changeset
  2011
0b76e67c2054 6947216: Even more Dual-pivot quicksort improvements
alanb
parents: 5506
diff changeset
  2012
    /**
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2013
     * The number of distinct char values.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2014
     */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2015
    private static final int NUM_CHAR_VALUES = 1 << 16;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2016
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2017
    /**
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2018
     * Sorts the specified range of the array using counting sort.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2019
     *
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2020
     * @param a the array to be sorted
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2021
     * @param low the index of the first element, inclusive, to be sorted
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2022
     * @param high the index of the last element, exclusive, to be sorted
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2023
     */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2024
    private static void countingSort(char[] a, int low, int high) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2025
        int[] count = new int[NUM_CHAR_VALUES];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2026
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2027
        /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2028
         * Compute a histogram with the number of each values.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2029
         */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2030
        for (int i = high; i > low; ++count[a[--i]]);
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2031
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2032
        /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2033
         * Place values on their final positions.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2034
         */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2035
        if (high - low > NUM_CHAR_VALUES) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2036
            for (int i = NUM_CHAR_VALUES; i > 0; ) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2037
                for (low = high - count[--i]; high > low;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2038
                    a[--high] = (char) i
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2039
                );
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2040
            }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2041
        } else {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2042
            for (int i = NUM_CHAR_VALUES; high > low; ) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2043
                while (count[--i] == 0);
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2044
                int c = count[i];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2045
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2046
                do {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2047
                    a[--high] = (char) i;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2048
                } while (--c > 0);
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2049
            }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2050
        }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2051
    }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2052
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2053
// [short]
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2054
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2055
    /**
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2056
     * Sorts the specified range of the array using
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2057
     * counting sort or Dual-Pivot Quicksort.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2058
     *
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2059
     * @param a the array to be sorted
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2060
     * @param low the index of the first element, inclusive, to be sorted
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2061
     * @param high the index of the last element, exclusive, to be sorted
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2062
     */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2063
    static void sort(short[] a, int low, int high) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2064
        if (high - low > MIN_SHORT_OR_CHAR_COUNTING_SORT_SIZE) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2065
            countingSort(a, low, high);
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2066
        } else {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2067
            sort(a, 0, low, high);
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2068
        }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2069
    }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2070
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2071
    /**
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2072
     * Sorts the specified array using the Dual-Pivot Quicksort and/or
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2073
     * other sorts in special-cases, possibly with parallel partitions.
4233
9b594a48d0f4 6899694: Dual-pivot quicksort improvements
alanb
parents: 4177
diff changeset
  2074
     *
9b594a48d0f4 6899694: Dual-pivot quicksort improvements
alanb
parents: 4177
diff changeset
  2075
     * @param a the array to be sorted
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2076
     * @param bits the combination of recursion depth and bit flag, where
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2077
     *        the right bit "0" indicates that array is the leftmost part
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2078
     * @param low the index of the first element, inclusive, to be sorted
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2079
     * @param high the index of the last element, exclusive, to be sorted
4233
9b594a48d0f4 6899694: Dual-pivot quicksort improvements
alanb
parents: 4177
diff changeset
  2080
     */
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2081
    static void sort(short[] a, int bits, int low, int high) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2082
        while (true) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2083
            int end = high - 1, size = high - low;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2084
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2085
            /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2086
             * Invoke insertion sort on small leftmost part.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2087
             */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2088
            if (size < MAX_INSERTION_SORT_SIZE) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2089
                insertionSort(a, low, high);
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2090
                return;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2091
            }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2092
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2093
            /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2094
             * Switch to counting sort if execution
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2095
             * time is becoming quadratic.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2096
             */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2097
            if ((bits += DELTA) > MAX_RECURSION_DEPTH) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2098
                countingSort(a, low, high);
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2099
                return;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2100
            }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2101
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2102
            /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2103
             * Use an inexpensive approximation of the golden ratio
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2104
             * to select five sample elements and determine pivots.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2105
             */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2106
            int step = (size >> 3) * 3 + 3;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2107
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2108
            /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2109
             * Five elements around (and including) the central element
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2110
             * will be used for pivot selection as described below. The
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2111
             * unequal choice of spacing these elements was empirically
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2112
             * determined to work well on a wide variety of inputs.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2113
             */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2114
            int e1 = low + step;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2115
            int e5 = end - step;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2116
            int e3 = (e1 + e5) >>> 1;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2117
            int e2 = (e1 + e3) >>> 1;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2118
            int e4 = (e3 + e5) >>> 1;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2119
            short a3 = a[e3];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2120
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2121
            /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2122
             * Sort these elements in place by the combination
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2123
             * of 4-element sorting network and insertion sort.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2124
             *
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2125
             *    5 ------o-----------o------------
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2126
             *            |           |
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2127
             *    4 ------|-----o-----o-----o------
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2128
             *            |     |           |
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2129
             *    2 ------o-----|-----o-----o------
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2130
             *                  |     |
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2131
             *    1 ------------o-----o------------
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2132
             */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2133
            if (a[e5] < a[e2]) { short t = a[e5]; a[e5] = a[e2]; a[e2] = t; }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2134
            if (a[e4] < a[e1]) { short t = a[e4]; a[e4] = a[e1]; a[e1] = t; }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2135
            if (a[e5] < a[e4]) { short t = a[e5]; a[e5] = a[e4]; a[e4] = t; }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2136
            if (a[e2] < a[e1]) { short t = a[e2]; a[e2] = a[e1]; a[e1] = t; }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2137
            if (a[e4] < a[e2]) { short t = a[e4]; a[e4] = a[e2]; a[e2] = t; }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2138
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2139
            if (a3 < a[e2]) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2140
                if (a3 < a[e1]) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2141
                    a[e3] = a[e2]; a[e2] = a[e1]; a[e1] = a3;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2142
                } else {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2143
                    a[e3] = a[e2]; a[e2] = a3;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2144
                }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2145
            } else if (a3 > a[e4]) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2146
                if (a3 > a[e5]) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2147
                    a[e3] = a[e4]; a[e4] = a[e5]; a[e5] = a3;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2148
                } else {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2149
                    a[e3] = a[e4]; a[e4] = a3;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2150
                }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2151
            }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2152
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2153
            // Pointers
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2154
            int lower = low; // The index of the last element of the left part
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2155
            int upper = end; // The index of the first element of the right part
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2156
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2157
            /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2158
             * Partitioning with 2 pivots in case of different elements.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2159
             */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2160
            if (a[e1] < a[e2] && a[e2] < a[e3] && a[e3] < a[e4] && a[e4] < a[e5]) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2161
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2162
                /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2163
                 * Use the first and fifth of the five sorted elements as
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2164
                 * the pivots. These values are inexpensive approximation
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2165
                 * of tertiles. Note, that pivot1 < pivot2.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2166
                 */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2167
                short pivot1 = a[e1];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2168
                short pivot2 = a[e5];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2169
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2170
                /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2171
                 * The first and the last elements to be sorted are moved
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2172
                 * to the locations formerly occupied by the pivots. When
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2173
                 * partitioning is completed, the pivots are swapped back
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2174
                 * into their final positions, and excluded from the next
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2175
                 * subsequent sorting.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2176
                 */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2177
                a[e1] = a[lower];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2178
                a[e5] = a[upper];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2179
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2180
                /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2181
                 * Skip elements, which are less or greater than the pivots.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2182
                 */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2183
                while (a[++lower] < pivot1);
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2184
                while (a[--upper] > pivot2);
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2185
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2186
                /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2187
                 * Backward 3-interval partitioning
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2188
                 *
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2189
                 *   left part                 central part          right part
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2190
                 * +------------------------------------------------------------+
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2191
                 * |  < pivot1  |   ?   |  pivot1 <= && <= pivot2  |  > pivot2  |
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2192
                 * +------------------------------------------------------------+
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2193
                 *             ^       ^                            ^
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2194
                 *             |       |                            |
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2195
                 *           lower     k                          upper
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2196
                 *
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2197
                 * Invariants:
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2198
                 *
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2199
                 *              all in (low, lower] < pivot1
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2200
                 *    pivot1 <= all in (k, upper)  <= pivot2
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2201
                 *              all in [upper, end) > pivot2
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2202
                 *
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2203
                 * Pointer k is the last index of ?-part
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2204
                 */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2205
                for (int unused = --lower, k = ++upper; --k > lower; ) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2206
                    short ak = a[k];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2207
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2208
                    if (ak < pivot1) { // Move a[k] to the left side
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2209
                        while (lower < k) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2210
                            if (a[++lower] >= pivot1) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2211
                                if (a[lower] > pivot2) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2212
                                    a[k] = a[--upper];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2213
                                    a[upper] = a[lower];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2214
                                } else {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2215
                                    a[k] = a[lower];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2216
                                }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2217
                                a[lower] = ak;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2218
                                break;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2219
                            }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2220
                        }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2221
                    } else if (ak > pivot2) { // Move a[k] to the right side
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2222
                        a[k] = a[--upper];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2223
                        a[upper] = ak;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2224
                    }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2225
                }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2226
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2227
                /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2228
                 * Swap the pivots into their final positions.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2229
                 */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2230
                a[low] = a[lower]; a[lower] = pivot1;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2231
                a[end] = a[upper]; a[upper] = pivot2;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2232
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2233
                /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2234
                 * Sort non-left parts recursively,
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2235
                 * excluding known pivots.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2236
                 */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2237
                sort(a, bits | 1, lower + 1, upper);
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2238
                sort(a, bits | 1, upper + 1, high);
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2239
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2240
            } else { // Use single pivot in case of many equal elements
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2241
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2242
                /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2243
                 * Use the third of the five sorted elements as the pivot.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2244
                 * This value is inexpensive approximation of the median.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2245
                 */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2246
                short pivot = a[e3];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2247
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2248
                /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2249
                 * The first element to be sorted is moved to the
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2250
                 * location formerly occupied by the pivot. After
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2251
                 * completion of partitioning the pivot is swapped
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2252
                 * back into its final position, and excluded from
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2253
                 * the next subsequent sorting.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2254
                 */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2255
                a[e3] = a[lower];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2256
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2257
                /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2258
                 * Traditional 3-way (Dutch National Flag) partitioning
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2259
                 *
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2260
                 *   left part                 central part    right part
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2261
                 * +------------------------------------------------------+
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2262
                 * |   < pivot   |     ?     |   == pivot   |   > pivot   |
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2263
                 * +------------------------------------------------------+
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2264
                 *              ^           ^                ^
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2265
                 *              |           |                |
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2266
                 *            lower         k              upper
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2267
                 *
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2268
                 * Invariants:
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2269
                 *
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2270
                 *   all in (low, lower] < pivot
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2271
                 *   all in (k, upper)  == pivot
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2272
                 *   all in [upper, end] > pivot
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2273
                 *
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2274
                 * Pointer k is the last index of ?-part
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2275
                 */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2276
                for (int k = ++upper; --k > lower; ) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2277
                    short ak = a[k];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2278
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2279
                    if (ak != pivot) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2280
                        a[k] = pivot;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2281
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2282
                        if (ak < pivot) { // Move a[k] to the left side
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2283
                            while (a[++lower] < pivot);
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2284
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2285
                            if (a[lower] > pivot) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2286
                                a[--upper] = a[lower];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2287
                            }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2288
                            a[lower] = ak;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2289
                        } else { // ak > pivot - Move a[k] to the right side
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2290
                            a[--upper] = ak;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2291
                        }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2292
                    }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2293
                }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2294
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2295
                /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2296
                 * Swap the pivot into its final position.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2297
                 */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2298
                a[low] = a[lower]; a[lower] = pivot;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2299
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2300
                /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2301
                 * Sort the right part, excluding known pivot.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2302
                 * All elements from the central part are
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2303
                 * equal and therefore already sorted.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2304
                 */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2305
                sort(a, bits | 1, upper, high);
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2306
            }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2307
            high = lower; // Iterate along the left part
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2308
        }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2309
    }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2310
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2311
    /**
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2312
     * Sorts the specified range of the array using insertion sort.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2313
     *
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2314
     * @param a the array to be sorted
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2315
     * @param low the index of the first element, inclusive, to be sorted
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2316
     * @param high the index of the last element, exclusive, to be sorted
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2317
     */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2318
    private static void insertionSort(short[] a, int low, int high) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2319
        for (int i, k = low; ++k < high; ) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2320
            short ai = a[i = k];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2321
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2322
            if (ai < a[i - 1]) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2323
                while (--i >= low && ai < a[i]) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2324
                    a[i + 1] = a[i];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2325
                }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2326
                a[i + 1] = ai;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2327
            }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2328
        }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2329
    }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2330
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2331
    /**
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2332
     * The number of distinct short values.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2333
     */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2334
    private static final int NUM_SHORT_VALUES = 1 << 16;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2335
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2336
    /**
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2337
     * Max index of short counter.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2338
     */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2339
    private static final int MAX_SHORT_INDEX = Short.MAX_VALUE + NUM_SHORT_VALUES + 1;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2340
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2341
    /**
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2342
     * Sorts the specified range of the array using counting sort.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2343
     *
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2344
     * @param a the array to be sorted
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2345
     * @param low the index of the first element, inclusive, to be sorted
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2346
     * @param high the index of the last element, exclusive, to be sorted
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2347
     */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2348
    private static void countingSort(short[] a, int low, int high) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2349
        int[] count = new int[NUM_SHORT_VALUES];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2350
4233
9b594a48d0f4 6899694: Dual-pivot quicksort improvements
alanb
parents: 4177
diff changeset
  2351
        /*
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2352
         * Compute a histogram with the number of each values.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2353
         */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2354
        for (int i = high; i > low; ++count[a[--i] & 0xFFFF]);
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2355
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2356
        /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2357
         * Place values on their final positions.
4233
9b594a48d0f4 6899694: Dual-pivot quicksort improvements
alanb
parents: 4177
diff changeset
  2358
         */
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2359
        if (high - low > NUM_SHORT_VALUES) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2360
            for (int i = MAX_SHORT_INDEX; --i > Short.MAX_VALUE; ) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2361
                int value = i & 0xFFFF;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2362
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2363
                for (low = high - count[value]; high > low;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2364
                    a[--high] = (short) value
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2365
                );
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2366
            }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2367
        } else {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2368
            for (int i = MAX_SHORT_INDEX; high > low; ) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2369
                while (count[--i & 0xFFFF] == 0);
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2370
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2371
                int value = i & 0xFFFF;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2372
                int c = count[value];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2373
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2374
                do {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2375
                    a[--high] = (short) value;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2376
                } while (--c > 0);
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2377
            }
5995
0b76e67c2054 6947216: Even more Dual-pivot quicksort improvements
alanb
parents: 5506
diff changeset
  2378
        }
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2379
    }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2380
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2381
// [float]
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2382
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2383
    /**
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2384
     * Sorts the specified range of the array using parallel merge
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2385
     * sort and/or Dual-Pivot Quicksort.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2386
     *
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2387
     * To balance the faster splitting and parallelism of merge sort
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2388
     * with the faster element partitioning of Quicksort, ranges are
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2389
     * subdivided in tiers such that, if there is enough parallelism,
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2390
     * the four-way parallel merge is started, still ensuring enough
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2391
     * parallelism to process the partitions.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2392
     *
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2393
     * @param a the array to be sorted
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2394
     * @param parallelism the parallelism level
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2395
     * @param low the index of the first element, inclusive, to be sorted
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2396
     * @param high the index of the last element, exclusive, to be sorted
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2397
     */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2398
    static void sort(float[] a, int parallelism, int low, int high) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2399
        /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2400
         * Phase 1. Count the number of negative zero -0.0f,
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2401
         * turn them into positive zero, and move all NaNs
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2402
         * to the end of the array.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2403
         */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2404
        int numNegativeZero = 0;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2405
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2406
        for (int k = high; k > low; ) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2407
            float ak = a[--k];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2408
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2409
            if (ak == 0.0f && Float.floatToRawIntBits(ak) < 0) { // ak is -0.0f
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2410
                numNegativeZero += 1;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2411
                a[k] = 0.0f;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2412
            } else if (ak != ak) { // ak is NaN
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2413
                a[k] = a[--high];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2414
                a[high] = ak;
4233
9b594a48d0f4 6899694: Dual-pivot quicksort improvements
alanb
parents: 4177
diff changeset
  2415
            }
9b594a48d0f4 6899694: Dual-pivot quicksort improvements
alanb
parents: 4177
diff changeset
  2416
        }
9b594a48d0f4 6899694: Dual-pivot quicksort improvements
alanb
parents: 4177
diff changeset
  2417
9b594a48d0f4 6899694: Dual-pivot quicksort improvements
alanb
parents: 4177
diff changeset
  2418
        /*
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2419
         * Phase 2. Sort everything except NaNs,
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2420
         * which are already in place.
4233
9b594a48d0f4 6899694: Dual-pivot quicksort improvements
alanb
parents: 4177
diff changeset
  2421
         */
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2422
        int size = high - low;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2423
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2424
        if (parallelism > 1 && size > MIN_PARALLEL_SORT_SIZE) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2425
            int depth = getDepth(parallelism, size >> 12);
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2426
            float[] b = depth == 0 ? null : new float[size];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2427
            new Sorter(null, a, b, low, size, low, depth).invoke();
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2428
        } else {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2429
            sort(null, a, 0, low, high);
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2430
        }
4233
9b594a48d0f4 6899694: Dual-pivot quicksort improvements
alanb
parents: 4177
diff changeset
  2431
5995
0b76e67c2054 6947216: Even more Dual-pivot quicksort improvements
alanb
parents: 5506
diff changeset
  2432
        /*
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2433
         * Phase 3. Turn positive zero 0.0f
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2434
         * back into negative zero -0.0f.
5995
0b76e67c2054 6947216: Even more Dual-pivot quicksort improvements
alanb
parents: 5506
diff changeset
  2435
         */
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2436
        if (++numNegativeZero == 1) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2437
            return;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2438
        }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2439
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2440
        /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2441
         * Find the position one less than
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2442
         * the index of the first zero.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2443
         */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2444
        while (low <= high) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2445
            int middle = (low + high) >>> 1;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2446
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2447
            if (a[middle] < 0) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2448
                low = middle + 1;
5995
0b76e67c2054 6947216: Even more Dual-pivot quicksort improvements
alanb
parents: 5506
diff changeset
  2449
            } else {
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2450
                high = middle - 1;
5995
0b76e67c2054 6947216: Even more Dual-pivot quicksort improvements
alanb
parents: 5506
diff changeset
  2451
            }
0b76e67c2054 6947216: Even more Dual-pivot quicksort improvements
alanb
parents: 5506
diff changeset
  2452
        }
0b76e67c2054 6947216: Even more Dual-pivot quicksort improvements
alanb
parents: 5506
diff changeset
  2453
0b76e67c2054 6947216: Even more Dual-pivot quicksort improvements
alanb
parents: 5506
diff changeset
  2454
        /*
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2455
         * Replace the required number of 0.0f by -0.0f.
5995
0b76e67c2054 6947216: Even more Dual-pivot quicksort improvements
alanb
parents: 5506
diff changeset
  2456
         */
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2457
        while (--numNegativeZero > 0) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2458
            a[++high] = -0.0f;
5995
0b76e67c2054 6947216: Even more Dual-pivot quicksort improvements
alanb
parents: 5506
diff changeset
  2459
        }
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2460
    }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2461
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2462
    /**
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2463
     * Sorts the specified array using the Dual-Pivot Quicksort and/or
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2464
     * other sorts in special-cases, possibly with parallel partitions.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2465
     *
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2466
     * @param sorter parallel context
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2467
     * @param a the array to be sorted
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2468
     * @param bits the combination of recursion depth and bit flag, where
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2469
     *        the right bit "0" indicates that array is the leftmost part
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2470
     * @param low the index of the first element, inclusive, to be sorted
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2471
     * @param high the index of the last element, exclusive, to be sorted
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2472
     */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2473
    static void sort(Sorter sorter, float[] a, int bits, int low, int high) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2474
        while (true) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2475
            int end = high - 1, size = high - low;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2476
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2477
            /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2478
             * Run mixed insertion sort on small non-leftmost parts.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2479
             */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2480
            if (size < MAX_MIXED_INSERTION_SORT_SIZE + bits && (bits & 1) > 0) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2481
                mixedInsertionSort(a, low, high - 3 * ((size >> 5) << 3), high);
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2482
                return;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2483
            }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2484
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2485
            /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2486
             * Invoke insertion sort on small leftmost part.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2487
             */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2488
            if (size < MAX_INSERTION_SORT_SIZE) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2489
                insertionSort(a, low, high);
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2490
                return;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2491
            }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2492
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2493
            /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2494
             * Check if the whole array or large non-leftmost
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2495
             * parts are nearly sorted and then merge runs.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2496
             */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2497
            if ((bits == 0 || size > MIN_TRY_MERGE_SIZE && (bits & 1) > 0)
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2498
                    && tryMergeRuns(sorter, a, low, size)) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2499
                return;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2500
            }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2501
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2502
            /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2503
             * Switch to heap sort if execution
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2504
             * time is becoming quadratic.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2505
             */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2506
            if ((bits += DELTA) > MAX_RECURSION_DEPTH) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2507
                heapSort(a, low, high);
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2508
                return;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2509
            }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2510
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2511
            /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2512
             * Use an inexpensive approximation of the golden ratio
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2513
             * to select five sample elements and determine pivots.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2514
             */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2515
            int step = (size >> 3) * 3 + 3;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2516
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2517
            /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2518
             * Five elements around (and including) the central element
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2519
             * will be used for pivot selection as described below. The
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2520
             * unequal choice of spacing these elements was empirically
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2521
             * determined to work well on a wide variety of inputs.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2522
             */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2523
            int e1 = low + step;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2524
            int e5 = end - step;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2525
            int e3 = (e1 + e5) >>> 1;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2526
            int e2 = (e1 + e3) >>> 1;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2527
            int e4 = (e3 + e5) >>> 1;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2528
            float a3 = a[e3];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2529
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2530
            /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2531
             * Sort these elements in place by the combination
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2532
             * of 4-element sorting network and insertion sort.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2533
             *
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2534
             *    5 ------o-----------o------------
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2535
             *            |           |
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2536
             *    4 ------|-----o-----o-----o------
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2537
             *            |     |           |
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2538
             *    2 ------o-----|-----o-----o------
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2539
             *                  |     |
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2540
             *    1 ------------o-----o------------
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2541
             */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2542
            if (a[e5] < a[e2]) { float t = a[e5]; a[e5] = a[e2]; a[e2] = t; }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2543
            if (a[e4] < a[e1]) { float t = a[e4]; a[e4] = a[e1]; a[e1] = t; }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2544
            if (a[e5] < a[e4]) { float t = a[e5]; a[e5] = a[e4]; a[e4] = t; }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2545
            if (a[e2] < a[e1]) { float t = a[e2]; a[e2] = a[e1]; a[e1] = t; }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2546
            if (a[e4] < a[e2]) { float t = a[e4]; a[e4] = a[e2]; a[e2] = t; }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2547
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2548
            if (a3 < a[e2]) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2549
                if (a3 < a[e1]) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2550
                    a[e3] = a[e2]; a[e2] = a[e1]; a[e1] = a3;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2551
                } else {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2552
                    a[e3] = a[e2]; a[e2] = a3;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2553
                }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2554
            } else if (a3 > a[e4]) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2555
                if (a3 > a[e5]) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2556
                    a[e3] = a[e4]; a[e4] = a[e5]; a[e5] = a3;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2557
                } else {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2558
                    a[e3] = a[e4]; a[e4] = a3;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2559
                }
5995
0b76e67c2054 6947216: Even more Dual-pivot quicksort improvements
alanb
parents: 5506
diff changeset
  2560
            }
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2561
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2562
            // Pointers
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2563
            int lower = low; // The index of the last element of the left part
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2564
            int upper = end; // The index of the first element of the right part
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2565
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2566
            /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2567
             * Partitioning with 2 pivots in case of different elements.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2568
             */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2569
            if (a[e1] < a[e2] && a[e2] < a[e3] && a[e3] < a[e4] && a[e4] < a[e5]) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2570
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2571
                /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2572
                 * Use the first and fifth of the five sorted elements as
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2573
                 * the pivots. These values are inexpensive approximation
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2574
                 * of tertiles. Note, that pivot1 < pivot2.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2575
                 */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2576
                float pivot1 = a[e1];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2577
                float pivot2 = a[e5];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2578
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2579
                /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2580
                 * The first and the last elements to be sorted are moved
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2581
                 * to the locations formerly occupied by the pivots. When
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2582
                 * partitioning is completed, the pivots are swapped back
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2583
                 * into their final positions, and excluded from the next
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2584
                 * subsequent sorting.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2585
                 */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2586
                a[e1] = a[lower];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2587
                a[e5] = a[upper];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2588
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2589
                /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2590
                 * Skip elements, which are less or greater than the pivots.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2591
                 */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2592
                while (a[++lower] < pivot1);
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2593
                while (a[--upper] > pivot2);
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2594
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2595
                /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2596
                 * Backward 3-interval partitioning
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2597
                 *
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2598
                 *   left part                 central part          right part
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2599
                 * +------------------------------------------------------------+
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2600
                 * |  < pivot1  |   ?   |  pivot1 <= && <= pivot2  |  > pivot2  |
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2601
                 * +------------------------------------------------------------+
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2602
                 *             ^       ^                            ^
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2603
                 *             |       |                            |
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2604
                 *           lower     k                          upper
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2605
                 *
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2606
                 * Invariants:
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2607
                 *
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2608
                 *              all in (low, lower] < pivot1
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2609
                 *    pivot1 <= all in (k, upper)  <= pivot2
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2610
                 *              all in [upper, end) > pivot2
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2611
                 *
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2612
                 * Pointer k is the last index of ?-part
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2613
                 */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2614
                for (int unused = --lower, k = ++upper; --k > lower; ) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2615
                    float ak = a[k];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2616
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2617
                    if (ak < pivot1) { // Move a[k] to the left side
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2618
                        while (lower < k) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2619
                            if (a[++lower] >= pivot1) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2620
                                if (a[lower] > pivot2) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2621
                                    a[k] = a[--upper];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2622
                                    a[upper] = a[lower];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2623
                                } else {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2624
                                    a[k] = a[lower];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2625
                                }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2626
                                a[lower] = ak;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2627
                                break;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2628
                            }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2629
                        }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2630
                    } else if (ak > pivot2) { // Move a[k] to the right side
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2631
                        a[k] = a[--upper];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2632
                        a[upper] = ak;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2633
                    }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2634
                }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2635
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2636
                /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2637
                 * Swap the pivots into their final positions.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2638
                 */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2639
                a[low] = a[lower]; a[lower] = pivot1;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2640
                a[end] = a[upper]; a[upper] = pivot2;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2641
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2642
                /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2643
                 * Sort non-left parts recursively (possibly in parallel),
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2644
                 * excluding known pivots.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2645
                 */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2646
                if (size > MIN_PARALLEL_SORT_SIZE && sorter != null) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2647
                    sorter.forkSorter(bits | 1, lower + 1, upper);
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2648
                    sorter.forkSorter(bits | 1, upper + 1, high);
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2649
                } else {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2650
                    sort(sorter, a, bits | 1, lower + 1, upper);
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2651
                    sort(sorter, a, bits | 1, upper + 1, high);
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2652
                }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2653
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2654
            } else { // Use single pivot in case of many equal elements
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2655
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2656
                /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2657
                 * Use the third of the five sorted elements as the pivot.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2658
                 * This value is inexpensive approximation of the median.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2659
                 */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2660
                float pivot = a[e3];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2661
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2662
                /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2663
                 * The first element to be sorted is moved to the
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2664
                 * location formerly occupied by the pivot. After
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2665
                 * completion of partitioning the pivot is swapped
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2666
                 * back into its final position, and excluded from
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2667
                 * the next subsequent sorting.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2668
                 */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2669
                a[e3] = a[lower];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2670
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2671
                /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2672
                 * Traditional 3-way (Dutch National Flag) partitioning
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2673
                 *
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2674
                 *   left part                 central part    right part
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2675
                 * +------------------------------------------------------+
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2676
                 * |   < pivot   |     ?     |   == pivot   |   > pivot   |
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2677
                 * +------------------------------------------------------+
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2678
                 *              ^           ^                ^
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2679
                 *              |           |                |
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2680
                 *            lower         k              upper
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2681
                 *
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2682
                 * Invariants:
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2683
                 *
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2684
                 *   all in (low, lower] < pivot
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2685
                 *   all in (k, upper)  == pivot
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2686
                 *   all in [upper, end] > pivot
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2687
                 *
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2688
                 * Pointer k is the last index of ?-part
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2689
                 */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2690
                for (int k = ++upper; --k > lower; ) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2691
                    float ak = a[k];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2692
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2693
                    if (ak != pivot) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2694
                        a[k] = pivot;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2695
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2696
                        if (ak < pivot) { // Move a[k] to the left side
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2697
                            while (a[++lower] < pivot);
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2698
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2699
                            if (a[lower] > pivot) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2700
                                a[--upper] = a[lower];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2701
                            }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2702
                            a[lower] = ak;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2703
                        } else { // ak > pivot - Move a[k] to the right side
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2704
                            a[--upper] = ak;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2705
                        }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2706
                    }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2707
                }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2708
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2709
                /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2710
                 * Swap the pivot into its final position.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2711
                 */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2712
                a[low] = a[lower]; a[lower] = pivot;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2713
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2714
                /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2715
                 * Sort the right part (possibly in parallel), excluding
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2716
                 * known pivot. All elements from the central part are
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2717
                 * equal and therefore already sorted.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2718
                 */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2719
                if (size > MIN_PARALLEL_SORT_SIZE && sorter != null) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2720
                    sorter.forkSorter(bits | 1, upper, high);
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2721
                } else {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2722
                    sort(sorter, a, bits | 1, upper, high);
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2723
                }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2724
            }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2725
            high = lower; // Iterate along the left part
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2726
        }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2727
    }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2728
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2729
    /**
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2730
     * Sorts the specified range of the array using mixed insertion sort.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2731
     *
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2732
     * Mixed insertion sort is combination of simple insertion sort,
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2733
     * pin insertion sort and pair insertion sort.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2734
     *
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2735
     * In the context of Dual-Pivot Quicksort, the pivot element
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2736
     * from the left part plays the role of sentinel, because it
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2737
     * is less than any elements from the given part. Therefore,
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2738
     * expensive check of the left range can be skipped on each
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2739
     * iteration unless it is the leftmost call.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2740
     *
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2741
     * @param a the array to be sorted
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2742
     * @param low the index of the first element, inclusive, to be sorted
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2743
     * @param end the index of the last element for simple insertion sort
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2744
     * @param high the index of the last element, exclusive, to be sorted
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2745
     */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2746
    private static void mixedInsertionSort(float[] a, int low, int end, int high) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2747
        if (end == high) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2748
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2749
            /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2750
             * Invoke simple insertion sort on tiny array.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2751
             */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2752
            for (int i; ++low < end; ) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2753
                float ai = a[i = low];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2754
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2755
                while (ai < a[--i]) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2756
                    a[i + 1] = a[i];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2757
                }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2758
                a[i + 1] = ai;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2759
            }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2760
        } else {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2761
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2762
            /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2763
             * Start with pin insertion sort on small part.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2764
             *
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2765
             * Pin insertion sort is extended simple insertion sort.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2766
             * The main idea of this sort is to put elements larger
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2767
             * than an element called pin to the end of array (the
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2768
             * proper area for such elements). It avoids expensive
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2769
             * movements of these elements through the whole array.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2770
             */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2771
            float pin = a[end];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2772
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2773
            for (int i, p = high; ++low < end; ) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2774
                float ai = a[i = low];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2775
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2776
                if (ai < a[i - 1]) { // Small element
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2777
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2778
                    /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2779
                     * Insert small element into sorted part.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2780
                     */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2781
                    a[i] = a[--i];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2782
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2783
                    while (ai < a[--i]) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2784
                        a[i + 1] = a[i];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2785
                    }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2786
                    a[i + 1] = ai;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2787
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2788
                } else if (p > i && ai > pin) { // Large element
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2789
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2790
                    /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2791
                     * Find element smaller than pin.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2792
                     */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2793
                    while (a[--p] > pin);
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2794
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2795
                    /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2796
                     * Swap it with large element.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2797
                     */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2798
                    if (p > i) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2799
                        ai = a[p];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2800
                        a[p] = a[i];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2801
                    }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2802
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2803
                    /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2804
                     * Insert small element into sorted part.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2805
                     */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2806
                    while (ai < a[--i]) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2807
                        a[i + 1] = a[i];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2808
                    }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2809
                    a[i + 1] = ai;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2810
                }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2811
            }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2812
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2813
            /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2814
             * Continue with pair insertion sort on remain part.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2815
             */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2816
            for (int i; low < high; ++low) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2817
                float a1 = a[i = low], a2 = a[++low];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2818
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2819
                /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2820
                 * Insert two elements per iteration: at first, insert the
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2821
                 * larger element and then insert the smaller element, but
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2822
                 * from the position where the larger element was inserted.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2823
                 */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2824
                if (a1 > a2) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2825
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2826
                    while (a1 < a[--i]) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2827
                        a[i + 2] = a[i];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2828
                    }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2829
                    a[++i + 1] = a1;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2830
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2831
                    while (a2 < a[--i]) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2832
                        a[i + 1] = a[i];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2833
                    }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2834
                    a[i + 1] = a2;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2835
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2836
                } else if (a1 < a[i - 1]) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2837
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2838
                    while (a2 < a[--i]) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2839
                        a[i + 2] = a[i];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2840
                    }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2841
                    a[++i + 1] = a2;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2842
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2843
                    while (a1 < a[--i]) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2844
                        a[i + 1] = a[i];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2845
                    }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2846
                    a[i + 1] = a1;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2847
                }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2848
            }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2849
        }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2850
    }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2851
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2852
    /**
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2853
     * Sorts the specified range of the array using insertion sort.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2854
     *
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2855
     * @param a the array to be sorted
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2856
     * @param low the index of the first element, inclusive, to be sorted
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2857
     * @param high the index of the last element, exclusive, to be sorted
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2858
     */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2859
    private static void insertionSort(float[] a, int low, int high) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2860
        for (int i, k = low; ++k < high; ) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2861
            float ai = a[i = k];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2862
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2863
            if (ai < a[i - 1]) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2864
                while (--i >= low && ai < a[i]) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2865
                    a[i + 1] = a[i];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2866
                }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2867
                a[i + 1] = ai;
4233
9b594a48d0f4 6899694: Dual-pivot quicksort improvements
alanb
parents: 4177
diff changeset
  2868
            }
9b594a48d0f4 6899694: Dual-pivot quicksort improvements
alanb
parents: 4177
diff changeset
  2869
        }
9b594a48d0f4 6899694: Dual-pivot quicksort improvements
alanb
parents: 4177
diff changeset
  2870
    }
9b594a48d0f4 6899694: Dual-pivot quicksort improvements
alanb
parents: 4177
diff changeset
  2871
9b594a48d0f4 6899694: Dual-pivot quicksort improvements
alanb
parents: 4177
diff changeset
  2872
    /**
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2873
     * Sorts the specified range of the array using heap sort.
8188
b90884cf34f5 7013585: Dual-pivot quicksort improvements for highly structured (nearly sorted) and data with small periods
alanb
parents: 6896
diff changeset
  2874
     *
b90884cf34f5 7013585: Dual-pivot quicksort improvements for highly structured (nearly sorted) and data with small periods
alanb
parents: 6896
diff changeset
  2875
     * @param a the array to be sorted
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2876
     * @param low the index of the first element, inclusive, to be sorted
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2877
     * @param high the index of the last element, exclusive, to be sorted
8188
b90884cf34f5 7013585: Dual-pivot quicksort improvements for highly structured (nearly sorted) and data with small periods
alanb
parents: 6896
diff changeset
  2878
     */
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2879
    private static void heapSort(float[] a, int low, int high) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2880
        for (int k = (low + high) >>> 1; k > low; ) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2881
            pushDown(a, --k, a[k], low, high);
8188
b90884cf34f5 7013585: Dual-pivot quicksort improvements for highly structured (nearly sorted) and data with small periods
alanb
parents: 6896
diff changeset
  2882
        }
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2883
        while (--high > low) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2884
            float max = a[low];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2885
            pushDown(a, low, a[high], low, high);
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2886
            a[high] = max;
8188
b90884cf34f5 7013585: Dual-pivot quicksort improvements for highly structured (nearly sorted) and data with small periods
alanb
parents: 6896
diff changeset
  2887
        }
b90884cf34f5 7013585: Dual-pivot quicksort improvements for highly structured (nearly sorted) and data with small periods
alanb
parents: 6896
diff changeset
  2888
    }
b90884cf34f5 7013585: Dual-pivot quicksort improvements for highly structured (nearly sorted) and data with small periods
alanb
parents: 6896
diff changeset
  2889
b90884cf34f5 7013585: Dual-pivot quicksort improvements for highly structured (nearly sorted) and data with small periods
alanb
parents: 6896
diff changeset
  2890
    /**
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2891
     * Pushes specified element down during heap sort.
4170
a94a6faf44e6 6880672: Replace quicksort in java.util.Arrays with dual-pivot implementation
alanb
parents:
diff changeset
  2892
     *
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2893
     * @param a the given array
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2894
     * @param p the start index
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2895
     * @param value the given element
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2896
     * @param low the index of the first element, inclusive, to be sorted
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2897
     * @param high the index of the last element, exclusive, to be sorted
4170
a94a6faf44e6 6880672: Replace quicksort in java.util.Arrays with dual-pivot implementation
alanb
parents:
diff changeset
  2898
     */
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2899
    private static void pushDown(float[] a, int p, float value, int low, int high) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2900
        for (int k ;; a[p] = a[p = k]) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2901
            k = (p << 1) - low + 2; // Index of the right child
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2902
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2903
            if (k > high) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2904
                break;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2905
            }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2906
            if (k == high || a[k] < a[k - 1]) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2907
                --k;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2908
            }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2909
            if (a[k] <= value) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2910
                break;
5995
0b76e67c2054 6947216: Even more Dual-pivot quicksort improvements
alanb
parents: 5506
diff changeset
  2911
            }
0b76e67c2054 6947216: Even more Dual-pivot quicksort improvements
alanb
parents: 5506
diff changeset
  2912
        }
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2913
        a[p] = value;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2914
    }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2915
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2916
    /**
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2917
     * Tries to sort the specified range of the array.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2918
     *
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2919
     * @param sorter parallel context
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2920
     * @param a the array to be sorted
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2921
     * @param low the index of the first element to be sorted
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2922
     * @param size the array size
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2923
     * @return true if finally sorted, false otherwise
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2924
     */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2925
    private static boolean tryMergeRuns(Sorter sorter, float[] a, int low, int size) {
5995
0b76e67c2054 6947216: Even more Dual-pivot quicksort improvements
alanb
parents: 5506
diff changeset
  2926
0b76e67c2054 6947216: Even more Dual-pivot quicksort improvements
alanb
parents: 5506
diff changeset
  2927
        /*
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2928
         * The run array is constructed only if initial runs are
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2929
         * long enough to continue, run[i] then holds start index
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2930
         * of the i-th sequence of elements in non-descending order.
5995
0b76e67c2054 6947216: Even more Dual-pivot quicksort improvements
alanb
parents: 5506
diff changeset
  2931
         */
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2932
        int[] run = null;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2933
        int high = low + size;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2934
        int count = 1, last = low;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2935
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2936
        /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2937
         * Identify all possible runs.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2938
         */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2939
        for (int k = low + 1; k < high; ) {
5995
0b76e67c2054 6947216: Even more Dual-pivot quicksort improvements
alanb
parents: 5506
diff changeset
  2940
4170
a94a6faf44e6 6880672: Replace quicksort in java.util.Arrays with dual-pivot implementation
alanb
parents:
diff changeset
  2941
            /*
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2942
             * Find the end index of the current run.
4170
a94a6faf44e6 6880672: Replace quicksort in java.util.Arrays with dual-pivot implementation
alanb
parents:
diff changeset
  2943
             */
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2944
            if (a[k - 1] < a[k]) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2945
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2946
                // Identify ascending sequence
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2947
                while (++k < high && a[k - 1] <= a[k]);
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2948
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2949
            } else if (a[k - 1] > a[k]) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2950
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2951
                // Identify descending sequence
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2952
                while (++k < high && a[k - 1] >= a[k]);
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2953
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2954
                // Reverse into ascending order
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2955
                for (int i = last - 1, j = k; ++i < --j && a[i] > a[j]; ) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2956
                    float ai = a[i]; a[i] = a[j]; a[j] = ai;
5995
0b76e67c2054 6947216: Even more Dual-pivot quicksort improvements
alanb
parents: 5506
diff changeset
  2957
                }
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2958
            } else { // Identify constant sequence
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2959
                for (float ak = a[k]; ++k < high && ak == a[k]; );
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2960
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2961
                if (k < high) {
4241
7d4f50f3806c 6901318: Yet more Dual-pivot quicksort improvements
alanb
parents: 4233
diff changeset
  2962
                    continue;
4170
a94a6faf44e6 6880672: Replace quicksort in java.util.Arrays with dual-pivot implementation
alanb
parents:
diff changeset
  2963
                }
a94a6faf44e6 6880672: Replace quicksort in java.util.Arrays with dual-pivot implementation
alanb
parents:
diff changeset
  2964
            }
4356
1f9c2400b8c5 6905046: More Dual-pivot quicksort improvements
jjb
parents: 4241
diff changeset
  2965
6896
d229d56fd918 6976036: Dual-pivot quicksort update (10/2010 tune-up)
alanb
parents: 5995
diff changeset
  2966
            /*
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2967
             * Check special cases.
6896
d229d56fd918 6976036: Dual-pivot quicksort update (10/2010 tune-up)
alanb
parents: 5995
diff changeset
  2968
             */
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2969
            if (run == null) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2970
                if (k == high) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2971
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2972
                    /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2973
                     * The array is monotonous sequence,
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2974
                     * and therefore already sorted.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2975
                     */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2976
                    return true;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2977
                }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2978
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2979
                if (k - low < MIN_FIRST_RUN_SIZE) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2980
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2981
                    /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2982
                     * The first run is too small
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2983
                     * to proceed with scanning.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2984
                     */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2985
                    return false;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2986
                }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2987
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2988
                run = new int[((size >> 10) | 0x7F) & 0x3FF];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2989
                run[0] = low;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2990
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2991
            } else if (a[last - 1] > a[last]) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2992
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2993
                if (count > (k - low) >> MIN_FIRST_RUNS_FACTOR) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2994
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2995
                    /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2996
                     * The first runs are not long
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2997
                     * enough to continue scanning.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2998
                     */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  2999
                    return false;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3000
                }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3001
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3002
                if (++count == MAX_RUN_CAPACITY) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3003
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3004
                    /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3005
                     * Array is not highly structured.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3006
                     */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3007
                    return false;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3008
                }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3009
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3010
                if (count == run.length) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3011
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3012
                    /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3013
                     * Increase capacity of index array.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3014
                     */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3015
                    run = Arrays.copyOf(run, count << 1);
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3016
                }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3017
            }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3018
            run[count] = (last = k);
4170
a94a6faf44e6 6880672: Replace quicksort in java.util.Arrays with dual-pivot implementation
alanb
parents:
diff changeset
  3019
        }
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3020
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3021
        /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3022
         * Merge runs of highly structured array.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3023
         */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3024
        if (count > 1) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3025
            float[] b; int offset = low;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3026
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3027
            if (sorter == null || (b = (float[]) sorter.b) == null) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3028
                b = new float[size];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3029
            } else {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3030
                offset = sorter.offset;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3031
            }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3032
            mergeRuns(a, b, offset, 1, sorter != null, run, 0, count);
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3033
        }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3034
        return true;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3035
    }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3036
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3037
    /**
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3038
     * Merges the specified runs.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3039
     *
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3040
     * @param a the source array
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3041
     * @param b the temporary buffer used in merging
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3042
     * @param offset the start index in the source, inclusive
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3043
     * @param aim specifies merging: to source ( > 0), buffer ( < 0) or any ( == 0)
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3044
     * @param parallel indicates whether merging is performed in parallel
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3045
     * @param run the start indexes of the runs, inclusive
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3046
     * @param lo the start index of the first run, inclusive
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3047
     * @param hi the start index of the last run, inclusive
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3048
     * @return the destination where runs are merged
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3049
     */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3050
    private static float[] mergeRuns(float[] a, float[] b, int offset,
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3051
            int aim, boolean parallel, int[] run, int lo, int hi) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3052
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3053
        if (hi - lo == 1) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3054
            if (aim >= 0) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3055
                return a;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3056
            }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3057
            for (int i = run[hi], j = i - offset, low = run[lo]; i > low;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3058
                b[--j] = a[--i]
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3059
            );
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3060
            return b;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3061
        }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3062
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3063
        /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3064
         * Split into approximately equal parts.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3065
         */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3066
        int mi = lo, rmi = (run[lo] + run[hi]) >>> 1;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3067
        while (run[++mi + 1] <= rmi);
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3068
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3069
        /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3070
         * Merge the left and right parts.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3071
         */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3072
        float[] a1, a2;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3073
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3074
        if (parallel && hi - lo > MIN_RUN_COUNT) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3075
            RunMerger merger = new RunMerger(a, b, offset, 0, run, mi, hi).forkMe();
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3076
            a1 = mergeRuns(a, b, offset, -aim, true, run, lo, mi);
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3077
            a2 = (float[]) merger.getDestination();
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3078
        } else {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3079
            a1 = mergeRuns(a, b, offset, -aim, false, run, lo, mi);
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3080
            a2 = mergeRuns(a, b, offset,    0, false, run, mi, hi);
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3081
        }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3082
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3083
        float[] dst = a1 == a ? b : a;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3084
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3085
        int k   = a1 == a ? run[lo] - offset : run[lo];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3086
        int lo1 = a1 == b ? run[lo] - offset : run[lo];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3087
        int hi1 = a1 == b ? run[mi] - offset : run[mi];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3088
        int lo2 = a2 == b ? run[mi] - offset : run[mi];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3089
        int hi2 = a2 == b ? run[hi] - offset : run[hi];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3090
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3091
        if (parallel) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3092
            new Merger(null, dst, k, a1, lo1, hi1, a2, lo2, hi2).invoke();
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3093
        } else {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3094
            mergeParts(null, dst, k, a1, lo1, hi1, a2, lo2, hi2);
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3095
        }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3096
        return dst;
4233
9b594a48d0f4 6899694: Dual-pivot quicksort improvements
alanb
parents: 4177
diff changeset
  3097
    }
9b594a48d0f4 6899694: Dual-pivot quicksort improvements
alanb
parents: 4177
diff changeset
  3098
9b594a48d0f4 6899694: Dual-pivot quicksort improvements
alanb
parents: 4177
diff changeset
  3099
    /**
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3100
     * Merges the sorted parts.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3101
     *
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3102
     * @param merger parallel context
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3103
     * @param dst the destination where parts are merged
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3104
     * @param k the start index of the destination, inclusive
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3105
     * @param a1 the first part
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3106
     * @param lo1 the start index of the first part, inclusive
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3107
     * @param hi1 the end index of the first part, exclusive
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3108
     * @param a2 the second part
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3109
     * @param lo2 the start index of the second part, inclusive
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3110
     * @param hi2 the end index of the second part, exclusive
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3111
     */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3112
    private static void mergeParts(Merger merger, float[] dst, int k,
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3113
            float[] a1, int lo1, int hi1, float[] a2, int lo2, int hi2) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3114
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3115
        if (merger != null && a1 == a2) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3116
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3117
            while (true) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3118
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3119
                /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3120
                 * The first part must be larger.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3121
                 */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3122
                if (hi1 - lo1 < hi2 - lo2) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3123
                    int lo = lo1; lo1 = lo2; lo2 = lo;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3124
                    int hi = hi1; hi1 = hi2; hi2 = hi;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3125
                }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3126
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3127
                /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3128
                 * Small parts will be merged sequentially.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3129
                 */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3130
                if (hi1 - lo1 < MIN_PARALLEL_MERGE_PARTS_SIZE) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3131
                    break;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3132
                }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3133
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3134
                /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3135
                 * Find the median of the larger part.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3136
                 */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3137
                int mi1 = (lo1 + hi1) >>> 1;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3138
                float key = a1[mi1];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3139
                int mi2 = hi2;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3140
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3141
                /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3142
                 * Partition the smaller part.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3143
                 */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3144
                for (int loo = lo2; loo < mi2; ) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3145
                    int t = (loo + mi2) >>> 1;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3146
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3147
                    if (key > a2[t]) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3148
                        loo = t + 1;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3149
                    } else {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3150
                        mi2 = t;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3151
                    }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3152
                }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3153
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3154
                int d = mi2 - lo2 + mi1 - lo1;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3155
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3156
                /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3157
                 * Merge the right sub-parts in parallel.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3158
                 */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3159
                merger.forkMerger(dst, k + d, a1, mi1, hi1, a2, mi2, hi2);
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3160
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3161
                /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3162
                 * Process the sub-left parts.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3163
                 */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3164
                hi1 = mi1;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3165
                hi2 = mi2;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3166
            }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3167
        }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3168
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3169
        /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3170
         * Merge small parts sequentially.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3171
         */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3172
        while (lo1 < hi1 && lo2 < hi2) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3173
            dst[k++] = a1[lo1] < a2[lo2] ? a1[lo1++] : a2[lo2++];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3174
        }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3175
        if (dst != a1 || k < lo1) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3176
            while (lo1 < hi1) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3177
                dst[k++] = a1[lo1++];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3178
            }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3179
        }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3180
        if (dst != a2 || k < lo2) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3181
            while (lo2 < hi2) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3182
                dst[k++] = a2[lo2++];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3183
            }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3184
        }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3185
    }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3186
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3187
// [double]
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3188
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3189
    /**
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3190
     * Sorts the specified range of the array using parallel merge
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3191
     * sort and/or Dual-Pivot Quicksort.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3192
     *
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3193
     * To balance the faster splitting and parallelism of merge sort
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3194
     * with the faster element partitioning of Quicksort, ranges are
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3195
     * subdivided in tiers such that, if there is enough parallelism,
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3196
     * the four-way parallel merge is started, still ensuring enough
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3197
     * parallelism to process the partitions.
4170
a94a6faf44e6 6880672: Replace quicksort in java.util.Arrays with dual-pivot implementation
alanb
parents:
diff changeset
  3198
     *
a94a6faf44e6 6880672: Replace quicksort in java.util.Arrays with dual-pivot implementation
alanb
parents:
diff changeset
  3199
     * @param a the array to be sorted
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3200
     * @param parallelism the parallelism level
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3201
     * @param low the index of the first element, inclusive, to be sorted
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3202
     * @param high the index of the last element, exclusive, to be sorted
4170
a94a6faf44e6 6880672: Replace quicksort in java.util.Arrays with dual-pivot implementation
alanb
parents:
diff changeset
  3203
     */
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3204
    static void sort(double[] a, int parallelism, int low, int high) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3205
        /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3206
         * Phase 1. Count the number of negative zero -0.0d,
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3207
         * turn them into positive zero, and move all NaNs
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3208
         * to the end of the array.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3209
         */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3210
        int numNegativeZero = 0;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3211
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3212
        for (int k = high; k > low; ) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3213
            double ak = a[--k];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3214
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3215
            if (ak == 0.0d && Double.doubleToRawLongBits(ak) < 0) { // ak is -0.0d
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3216
                numNegativeZero += 1;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3217
                a[k] = 0.0d;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3218
            } else if (ak != ak) { // ak is NaN
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3219
                a[k] = a[--high];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3220
                a[high] = ak;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3221
            }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3222
        }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3223
4233
9b594a48d0f4 6899694: Dual-pivot quicksort improvements
alanb
parents: 4177
diff changeset
  3224
        /*
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3225
         * Phase 2. Sort everything except NaNs,
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3226
         * which are already in place.
4233
9b594a48d0f4 6899694: Dual-pivot quicksort improvements
alanb
parents: 4177
diff changeset
  3227
         */
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3228
        int size = high - low;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3229
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3230
        if (parallelism > 1 && size > MIN_PARALLEL_SORT_SIZE) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3231
            int depth = getDepth(parallelism, size >> 12);
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3232
            double[] b = depth == 0 ? null : new double[size];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3233
            new Sorter(null, a, b, low, size, low, depth).invoke();
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3234
        } else {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3235
            sort(null, a, 0, low, high);
5995
0b76e67c2054 6947216: Even more Dual-pivot quicksort improvements
alanb
parents: 5506
diff changeset
  3236
        }
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3237
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3238
        /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3239
         * Phase 3. Turn positive zero 0.0d
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3240
         * back into negative zero -0.0d.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3241
         */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3242
        if (++numNegativeZero == 1) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3243
            return;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3244
        }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3245
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3246
        /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3247
         * Find the position one less than
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3248
         * the index of the first zero.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3249
         */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3250
        while (low <= high) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3251
            int middle = (low + high) >>> 1;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3252
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3253
            if (a[middle] < 0) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3254
                low = middle + 1;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3255
            } else {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3256
                high = middle - 1;
4233
9b594a48d0f4 6899694: Dual-pivot quicksort improvements
alanb
parents: 4177
diff changeset
  3257
            }
9b594a48d0f4 6899694: Dual-pivot quicksort improvements
alanb
parents: 4177
diff changeset
  3258
        }
9b594a48d0f4 6899694: Dual-pivot quicksort improvements
alanb
parents: 4177
diff changeset
  3259
9b594a48d0f4 6899694: Dual-pivot quicksort improvements
alanb
parents: 4177
diff changeset
  3260
        /*
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3261
         * Replace the required number of 0.0d by -0.0d.
5995
0b76e67c2054 6947216: Even more Dual-pivot quicksort improvements
alanb
parents: 5506
diff changeset
  3262
         */
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3263
        while (--numNegativeZero > 0) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3264
            a[++high] = -0.0d;
5995
0b76e67c2054 6947216: Even more Dual-pivot quicksort improvements
alanb
parents: 5506
diff changeset
  3265
        }
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3266
    }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3267
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3268
    /**
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3269
     * Sorts the specified array using the Dual-Pivot Quicksort and/or
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3270
     * other sorts in special-cases, possibly with parallel partitions.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3271
     *
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3272
     * @param sorter parallel context
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3273
     * @param a the array to be sorted
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3274
     * @param bits the combination of recursion depth and bit flag, where
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3275
     *        the right bit "0" indicates that array is the leftmost part
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3276
     * @param low the index of the first element, inclusive, to be sorted
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3277
     * @param high the index of the last element, exclusive, to be sorted
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3278
     */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3279
    static void sort(Sorter sorter, double[] a, int bits, int low, int high) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3280
        while (true) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3281
            int end = high - 1, size = high - low;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3282
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3283
            /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3284
             * Run mixed insertion sort on small non-leftmost parts.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3285
             */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3286
            if (size < MAX_MIXED_INSERTION_SORT_SIZE + bits && (bits & 1) > 0) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3287
                mixedInsertionSort(a, low, high - 3 * ((size >> 5) << 3), high);
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3288
                return;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3289
            }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3290
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3291
            /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3292
             * Invoke insertion sort on small leftmost part.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3293
             */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3294
            if (size < MAX_INSERTION_SORT_SIZE) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3295
                insertionSort(a, low, high);
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3296
                return;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3297
            }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3298
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3299
            /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3300
             * Check if the whole array or large non-leftmost
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3301
             * parts are nearly sorted and then merge runs.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3302
             */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3303
            if ((bits == 0 || size > MIN_TRY_MERGE_SIZE && (bits & 1) > 0)
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3304
                    && tryMergeRuns(sorter, a, low, size)) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3305
                return;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3306
            }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3307
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3308
            /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3309
             * Switch to heap sort if execution
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3310
             * time is becoming quadratic.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3311
             */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3312
            if ((bits += DELTA) > MAX_RECURSION_DEPTH) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3313
                heapSort(a, low, high);
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3314
                return;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3315
            }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3316
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3317
            /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3318
             * Use an inexpensive approximation of the golden ratio
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3319
             * to select five sample elements and determine pivots.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3320
             */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3321
            int step = (size >> 3) * 3 + 3;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3322
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3323
            /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3324
             * Five elements around (and including) the central element
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3325
             * will be used for pivot selection as described below. The
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3326
             * unequal choice of spacing these elements was empirically
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3327
             * determined to work well on a wide variety of inputs.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3328
             */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3329
            int e1 = low + step;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3330
            int e5 = end - step;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3331
            int e3 = (e1 + e5) >>> 1;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3332
            int e2 = (e1 + e3) >>> 1;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3333
            int e4 = (e3 + e5) >>> 1;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3334
            double a3 = a[e3];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3335
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3336
            /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3337
             * Sort these elements in place by the combination
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3338
             * of 4-element sorting network and insertion sort.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3339
             *
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3340
             *    5 ------o-----------o------------
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3341
             *            |           |
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3342
             *    4 ------|-----o-----o-----o------
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3343
             *            |     |           |
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3344
             *    2 ------o-----|-----o-----o------
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3345
             *                  |     |
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3346
             *    1 ------------o-----o------------
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3347
             */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3348
            if (a[e5] < a[e2]) { double t = a[e5]; a[e5] = a[e2]; a[e2] = t; }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3349
            if (a[e4] < a[e1]) { double t = a[e4]; a[e4] = a[e1]; a[e1] = t; }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3350
            if (a[e5] < a[e4]) { double t = a[e5]; a[e5] = a[e4]; a[e4] = t; }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3351
            if (a[e2] < a[e1]) { double t = a[e2]; a[e2] = a[e1]; a[e1] = t; }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3352
            if (a[e4] < a[e2]) { double t = a[e4]; a[e4] = a[e2]; a[e2] = t; }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3353
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3354
            if (a3 < a[e2]) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3355
                if (a3 < a[e1]) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3356
                    a[e3] = a[e2]; a[e2] = a[e1]; a[e1] = a3;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3357
                } else {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3358
                    a[e3] = a[e2]; a[e2] = a3;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3359
                }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3360
            } else if (a3 > a[e4]) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3361
                if (a3 > a[e5]) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3362
                    a[e3] = a[e4]; a[e4] = a[e5]; a[e5] = a3;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3363
                } else {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3364
                    a[e3] = a[e4]; a[e4] = a3;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3365
                }
5995
0b76e67c2054 6947216: Even more Dual-pivot quicksort improvements
alanb
parents: 5506
diff changeset
  3366
            }
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3367
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3368
            // Pointers
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3369
            int lower = low; // The index of the last element of the left part
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3370
            int upper = end; // The index of the first element of the right part
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3371
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3372
            /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3373
             * Partitioning with 2 pivots in case of different elements.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3374
             */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3375
            if (a[e1] < a[e2] && a[e2] < a[e3] && a[e3] < a[e4] && a[e4] < a[e5]) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3376
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3377
                /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3378
                 * Use the first and fifth of the five sorted elements as
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3379
                 * the pivots. These values are inexpensive approximation
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3380
                 * of tertiles. Note, that pivot1 < pivot2.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3381
                 */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3382
                double pivot1 = a[e1];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3383
                double pivot2 = a[e5];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3384
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3385
                /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3386
                 * The first and the last elements to be sorted are moved
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3387
                 * to the locations formerly occupied by the pivots. When
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3388
                 * partitioning is completed, the pivots are swapped back
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3389
                 * into their final positions, and excluded from the next
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3390
                 * subsequent sorting.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3391
                 */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3392
                a[e1] = a[lower];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3393
                a[e5] = a[upper];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3394
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3395
                /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3396
                 * Skip elements, which are less or greater than the pivots.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3397
                 */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3398
                while (a[++lower] < pivot1);
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3399
                while (a[--upper] > pivot2);
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3400
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3401
                /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3402
                 * Backward 3-interval partitioning
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3403
                 *
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3404
                 *   left part                 central part          right part
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3405
                 * +------------------------------------------------------------+
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3406
                 * |  < pivot1  |   ?   |  pivot1 <= && <= pivot2  |  > pivot2  |
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3407
                 * +------------------------------------------------------------+
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3408
                 *             ^       ^                            ^
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3409
                 *             |       |                            |
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3410
                 *           lower     k                          upper
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3411
                 *
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3412
                 * Invariants:
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3413
                 *
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3414
                 *              all in (low, lower] < pivot1
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3415
                 *    pivot1 <= all in (k, upper)  <= pivot2
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3416
                 *              all in [upper, end) > pivot2
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3417
                 *
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3418
                 * Pointer k is the last index of ?-part
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3419
                 */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3420
                for (int unused = --lower, k = ++upper; --k > lower; ) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3421
                    double ak = a[k];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3422
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3423
                    if (ak < pivot1) { // Move a[k] to the left side
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3424
                        while (lower < k) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3425
                            if (a[++lower] >= pivot1) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3426
                                if (a[lower] > pivot2) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3427
                                    a[k] = a[--upper];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3428
                                    a[upper] = a[lower];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3429
                                } else {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3430
                                    a[k] = a[lower];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3431
                                }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3432
                                a[lower] = ak;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3433
                                break;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3434
                            }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3435
                        }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3436
                    } else if (ak > pivot2) { // Move a[k] to the right side
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3437
                        a[k] = a[--upper];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3438
                        a[upper] = ak;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3439
                    }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3440
                }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3441
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3442
                /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3443
                 * Swap the pivots into their final positions.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3444
                 */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3445
                a[low] = a[lower]; a[lower] = pivot1;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3446
                a[end] = a[upper]; a[upper] = pivot2;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3447
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3448
                /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3449
                 * Sort non-left parts recursively (possibly in parallel),
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3450
                 * excluding known pivots.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3451
                 */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3452
                if (size > MIN_PARALLEL_SORT_SIZE && sorter != null) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3453
                    sorter.forkSorter(bits | 1, lower + 1, upper);
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3454
                    sorter.forkSorter(bits | 1, upper + 1, high);
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3455
                } else {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3456
                    sort(sorter, a, bits | 1, lower + 1, upper);
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3457
                    sort(sorter, a, bits | 1, upper + 1, high);
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3458
                }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3459
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3460
            } else { // Use single pivot in case of many equal elements
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3461
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3462
                /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3463
                 * Use the third of the five sorted elements as the pivot.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3464
                 * This value is inexpensive approximation of the median.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3465
                 */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3466
                double pivot = a[e3];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3467
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3468
                /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3469
                 * The first element to be sorted is moved to the
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3470
                 * location formerly occupied by the pivot. After
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3471
                 * completion of partitioning the pivot is swapped
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3472
                 * back into its final position, and excluded from
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3473
                 * the next subsequent sorting.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3474
                 */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3475
                a[e3] = a[lower];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3476
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3477
                /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3478
                 * Traditional 3-way (Dutch National Flag) partitioning
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3479
                 *
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3480
                 *   left part                 central part    right part
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3481
                 * +------------------------------------------------------+
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3482
                 * |   < pivot   |     ?     |   == pivot   |   > pivot   |
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3483
                 * +------------------------------------------------------+
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3484
                 *              ^           ^                ^
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3485
                 *              |           |                |
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3486
                 *            lower         k              upper
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3487
                 *
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3488
                 * Invariants:
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3489
                 *
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3490
                 *   all in (low, lower] < pivot
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3491
                 *   all in (k, upper)  == pivot
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3492
                 *   all in [upper, end] > pivot
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3493
                 *
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3494
                 * Pointer k is the last index of ?-part
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3495
                 */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3496
                for (int k = ++upper; --k > lower; ) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3497
                    double ak = a[k];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3498
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3499
                    if (ak != pivot) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3500
                        a[k] = pivot;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3501
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3502
                        if (ak < pivot) { // Move a[k] to the left side
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3503
                            while (a[++lower] < pivot);
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3504
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3505
                            if (a[lower] > pivot) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3506
                                a[--upper] = a[lower];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3507
                            }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3508
                            a[lower] = ak;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3509
                        } else { // ak > pivot - Move a[k] to the right side
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3510
                            a[--upper] = ak;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3511
                        }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3512
                    }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3513
                }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3514
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3515
                /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3516
                 * Swap the pivot into its final position.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3517
                 */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3518
                a[low] = a[lower]; a[lower] = pivot;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3519
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3520
                /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3521
                 * Sort the right part (possibly in parallel), excluding
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3522
                 * known pivot. All elements from the central part are
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3523
                 * equal and therefore already sorted.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3524
                 */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3525
                if (size > MIN_PARALLEL_SORT_SIZE && sorter != null) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3526
                    sorter.forkSorter(bits | 1, upper, high);
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3527
                } else {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3528
                    sort(sorter, a, bits | 1, upper, high);
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3529
                }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3530
            }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3531
            high = lower; // Iterate along the left part
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3532
        }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3533
    }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3534
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3535
    /**
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3536
     * Sorts the specified range of the array using mixed insertion sort.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3537
     *
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3538
     * Mixed insertion sort is combination of simple insertion sort,
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3539
     * pin insertion sort and pair insertion sort.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3540
     *
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3541
     * In the context of Dual-Pivot Quicksort, the pivot element
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3542
     * from the left part plays the role of sentinel, because it
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3543
     * is less than any elements from the given part. Therefore,
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3544
     * expensive check of the left range can be skipped on each
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3545
     * iteration unless it is the leftmost call.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3546
     *
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3547
     * @param a the array to be sorted
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3548
     * @param low the index of the first element, inclusive, to be sorted
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3549
     * @param end the index of the last element for simple insertion sort
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3550
     * @param high the index of the last element, exclusive, to be sorted
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3551
     */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3552
    private static void mixedInsertionSort(double[] a, int low, int end, int high) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3553
        if (end == high) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3554
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3555
            /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3556
             * Invoke simple insertion sort on tiny array.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3557
             */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3558
            for (int i; ++low < end; ) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3559
                double ai = a[i = low];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3560
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3561
                while (ai < a[--i]) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3562
                    a[i + 1] = a[i];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3563
                }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3564
                a[i + 1] = ai;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3565
            }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3566
        } else {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3567
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3568
            /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3569
             * Start with pin insertion sort on small part.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3570
             *
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3571
             * Pin insertion sort is extended simple insertion sort.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3572
             * The main idea of this sort is to put elements larger
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3573
             * than an element called pin to the end of array (the
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3574
             * proper area for such elements). It avoids expensive
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3575
             * movements of these elements through the whole array.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3576
             */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3577
            double pin = a[end];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3578
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3579
            for (int i, p = high; ++low < end; ) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3580
                double ai = a[i = low];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3581
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3582
                if (ai < a[i - 1]) { // Small element
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3583
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3584
                    /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3585
                     * Insert small element into sorted part.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3586
                     */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3587
                    a[i] = a[--i];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3588
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3589
                    while (ai < a[--i]) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3590
                        a[i + 1] = a[i];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3591
                    }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3592
                    a[i + 1] = ai;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3593
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3594
                } else if (p > i && ai > pin) { // Large element
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3595
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3596
                    /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3597
                     * Find element smaller than pin.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3598
                     */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3599
                    while (a[--p] > pin);
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3600
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3601
                    /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3602
                     * Swap it with large element.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3603
                     */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3604
                    if (p > i) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3605
                        ai = a[p];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3606
                        a[p] = a[i];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3607
                    }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3608
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3609
                    /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3610
                     * Insert small element into sorted part.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3611
                     */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3612
                    while (ai < a[--i]) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3613
                        a[i + 1] = a[i];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3614
                    }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3615
                    a[i + 1] = ai;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3616
                }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3617
            }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3618
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3619
            /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3620
             * Continue with pair insertion sort on remain part.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3621
             */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3622
            for (int i; low < high; ++low) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3623
                double a1 = a[i = low], a2 = a[++low];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3624
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3625
                /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3626
                 * Insert two elements per iteration: at first, insert the
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3627
                 * larger element and then insert the smaller element, but
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3628
                 * from the position where the larger element was inserted.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3629
                 */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3630
                if (a1 > a2) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3631
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3632
                    while (a1 < a[--i]) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3633
                        a[i + 2] = a[i];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3634
                    }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3635
                    a[++i + 1] = a1;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3636
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3637
                    while (a2 < a[--i]) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3638
                        a[i + 1] = a[i];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3639
                    }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3640
                    a[i + 1] = a2;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3641
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3642
                } else if (a1 < a[i - 1]) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3643
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3644
                    while (a2 < a[--i]) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3645
                        a[i + 2] = a[i];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3646
                    }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3647
                    a[++i + 1] = a2;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3648
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3649
                    while (a1 < a[--i]) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3650
                        a[i + 1] = a[i];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3651
                    }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3652
                    a[i + 1] = a1;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3653
                }
4233
9b594a48d0f4 6899694: Dual-pivot quicksort improvements
alanb
parents: 4177
diff changeset
  3654
            }
9b594a48d0f4 6899694: Dual-pivot quicksort improvements
alanb
parents: 4177
diff changeset
  3655
        }
9b594a48d0f4 6899694: Dual-pivot quicksort improvements
alanb
parents: 4177
diff changeset
  3656
    }
9b594a48d0f4 6899694: Dual-pivot quicksort improvements
alanb
parents: 4177
diff changeset
  3657
9b594a48d0f4 6899694: Dual-pivot quicksort improvements
alanb
parents: 4177
diff changeset
  3658
    /**
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3659
     * Sorts the specified range of the array using insertion sort.
8188
b90884cf34f5 7013585: Dual-pivot quicksort improvements for highly structured (nearly sorted) and data with small periods
alanb
parents: 6896
diff changeset
  3660
     *
b90884cf34f5 7013585: Dual-pivot quicksort improvements for highly structured (nearly sorted) and data with small periods
alanb
parents: 6896
diff changeset
  3661
     * @param a the array to be sorted
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3662
     * @param low the index of the first element, inclusive, to be sorted
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3663
     * @param high the index of the last element, exclusive, to be sorted
8188
b90884cf34f5 7013585: Dual-pivot quicksort improvements for highly structured (nearly sorted) and data with small periods
alanb
parents: 6896
diff changeset
  3664
     */
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3665
    private static void insertionSort(double[] a, int low, int high) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3666
        for (int i, k = low; ++k < high; ) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3667
            double ai = a[i = k];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3668
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3669
            if (ai < a[i - 1]) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3670
                while (--i >= low && ai < a[i]) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3671
                    a[i + 1] = a[i];
8188
b90884cf34f5 7013585: Dual-pivot quicksort improvements for highly structured (nearly sorted) and data with small periods
alanb
parents: 6896
diff changeset
  3672
                }
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3673
                a[i + 1] = ai;
8188
b90884cf34f5 7013585: Dual-pivot quicksort improvements for highly structured (nearly sorted) and data with small periods
alanb
parents: 6896
diff changeset
  3674
            }
b90884cf34f5 7013585: Dual-pivot quicksort improvements for highly structured (nearly sorted) and data with small periods
alanb
parents: 6896
diff changeset
  3675
        }
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3676
    }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3677
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3678
    /**
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3679
     * Sorts the specified range of the array using heap sort.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3680
     *
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3681
     * @param a the array to be sorted
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3682
     * @param low the index of the first element, inclusive, to be sorted
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3683
     * @param high the index of the last element, exclusive, to be sorted
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3684
     */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3685
    private static void heapSort(double[] a, int low, int high) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3686
        for (int k = (low + high) >>> 1; k > low; ) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3687
            pushDown(a, --k, a[k], low, high);
8188
b90884cf34f5 7013585: Dual-pivot quicksort improvements for highly structured (nearly sorted) and data with small periods
alanb
parents: 6896
diff changeset
  3688
        }
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3689
        while (--high > low) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3690
            double max = a[low];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3691
            pushDown(a, low, a[high], low, high);
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3692
            a[high] = max;
8188
b90884cf34f5 7013585: Dual-pivot quicksort improvements for highly structured (nearly sorted) and data with small periods
alanb
parents: 6896
diff changeset
  3693
        }
b90884cf34f5 7013585: Dual-pivot quicksort improvements for highly structured (nearly sorted) and data with small periods
alanb
parents: 6896
diff changeset
  3694
    }
b90884cf34f5 7013585: Dual-pivot quicksort improvements for highly structured (nearly sorted) and data with small periods
alanb
parents: 6896
diff changeset
  3695
b90884cf34f5 7013585: Dual-pivot quicksort improvements for highly structured (nearly sorted) and data with small periods
alanb
parents: 6896
diff changeset
  3696
    /**
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3697
     * Pushes specified element down during heap sort.
4170
a94a6faf44e6 6880672: Replace quicksort in java.util.Arrays with dual-pivot implementation
alanb
parents:
diff changeset
  3698
     *
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3699
     * @param a the given array
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3700
     * @param p the start index
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3701
     * @param value the given element
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3702
     * @param low the index of the first element, inclusive, to be sorted
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3703
     * @param high the index of the last element, exclusive, to be sorted
4170
a94a6faf44e6 6880672: Replace quicksort in java.util.Arrays with dual-pivot implementation
alanb
parents:
diff changeset
  3704
     */
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3705
    private static void pushDown(double[] a, int p, double value, int low, int high) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3706
        for (int k ;; a[p] = a[p = k]) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3707
            k = (p << 1) - low + 2; // Index of the right child
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3708
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3709
            if (k > high) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3710
                break;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3711
            }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3712
            if (k == high || a[k] < a[k - 1]) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3713
                --k;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3714
            }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3715
            if (a[k] <= value) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3716
                break;
5995
0b76e67c2054 6947216: Even more Dual-pivot quicksort improvements
alanb
parents: 5506
diff changeset
  3717
            }
0b76e67c2054 6947216: Even more Dual-pivot quicksort improvements
alanb
parents: 5506
diff changeset
  3718
        }
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3719
        a[p] = value;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3720
    }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3721
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3722
    /**
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3723
     * Tries to sort the specified range of the array.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3724
     *
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3725
     * @param sorter parallel context
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3726
     * @param a the array to be sorted
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3727
     * @param low the index of the first element to be sorted
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3728
     * @param size the array size
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3729
     * @return true if finally sorted, false otherwise
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3730
     */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3731
    private static boolean tryMergeRuns(Sorter sorter, double[] a, int low, int size) {
5995
0b76e67c2054 6947216: Even more Dual-pivot quicksort improvements
alanb
parents: 5506
diff changeset
  3732
0b76e67c2054 6947216: Even more Dual-pivot quicksort improvements
alanb
parents: 5506
diff changeset
  3733
        /*
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3734
         * The run array is constructed only if initial runs are
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3735
         * long enough to continue, run[i] then holds start index
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3736
         * of the i-th sequence of elements in non-descending order.
5995
0b76e67c2054 6947216: Even more Dual-pivot quicksort improvements
alanb
parents: 5506
diff changeset
  3737
         */
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3738
        int[] run = null;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3739
        int high = low + size;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3740
        int count = 1, last = low;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3741
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3742
        /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3743
         * Identify all possible runs.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3744
         */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3745
        for (int k = low + 1; k < high; ) {
5995
0b76e67c2054 6947216: Even more Dual-pivot quicksort improvements
alanb
parents: 5506
diff changeset
  3746
4170
a94a6faf44e6 6880672: Replace quicksort in java.util.Arrays with dual-pivot implementation
alanb
parents:
diff changeset
  3747
            /*
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3748
             * Find the end index of the current run.
4170
a94a6faf44e6 6880672: Replace quicksort in java.util.Arrays with dual-pivot implementation
alanb
parents:
diff changeset
  3749
             */
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3750
            if (a[k - 1] < a[k]) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3751
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3752
                // Identify ascending sequence
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3753
                while (++k < high && a[k - 1] <= a[k]);
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3754
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3755
            } else if (a[k - 1] > a[k]) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3756
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3757
                // Identify descending sequence
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3758
                while (++k < high && a[k - 1] >= a[k]);
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3759
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3760
                // Reverse into ascending order
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3761
                for (int i = last - 1, j = k; ++i < --j && a[i] > a[j]; ) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3762
                    double ai = a[i]; a[i] = a[j]; a[j] = ai;
5995
0b76e67c2054 6947216: Even more Dual-pivot quicksort improvements
alanb
parents: 5506
diff changeset
  3763
                }
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3764
            } else { // Identify constant sequence
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3765
                for (double ak = a[k]; ++k < high && ak == a[k]; );
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3766
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3767
                if (k < high) {
4241
7d4f50f3806c 6901318: Yet more Dual-pivot quicksort improvements
alanb
parents: 4233
diff changeset
  3768
                    continue;
4170
a94a6faf44e6 6880672: Replace quicksort in java.util.Arrays with dual-pivot implementation
alanb
parents:
diff changeset
  3769
                }
a94a6faf44e6 6880672: Replace quicksort in java.util.Arrays with dual-pivot implementation
alanb
parents:
diff changeset
  3770
            }
4356
1f9c2400b8c5 6905046: More Dual-pivot quicksort improvements
jjb
parents: 4241
diff changeset
  3771
6896
d229d56fd918 6976036: Dual-pivot quicksort update (10/2010 tune-up)
alanb
parents: 5995
diff changeset
  3772
            /*
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3773
             * Check special cases.
6896
d229d56fd918 6976036: Dual-pivot quicksort update (10/2010 tune-up)
alanb
parents: 5995
diff changeset
  3774
             */
59042
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3775
            if (run == null) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3776
                if (k == high) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3777
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3778
                    /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3779
                     * The array is monotonous sequence,
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3780
                     * and therefore already sorted.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3781
                     */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3782
                    return true;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3783
                }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3784
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3785
                if (k - low < MIN_FIRST_RUN_SIZE) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3786
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3787
                    /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3788
                     * The first run is too small
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3789
                     * to proceed with scanning.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3790
                     */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3791
                    return false;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3792
                }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3793
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3794
                run = new int[((size >> 10) | 0x7F) & 0x3FF];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3795
                run[0] = low;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3796
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3797
            } else if (a[last - 1] > a[last]) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3798
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3799
                if (count > (k - low) >> MIN_FIRST_RUNS_FACTOR) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3800
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3801
                    /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3802
                     * The first runs are not long
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3803
                     * enough to continue scanning.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3804
                     */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3805
                    return false;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3806
                }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3807
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3808
                if (++count == MAX_RUN_CAPACITY) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3809
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3810
                    /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3811
                     * Array is not highly structured.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3812
                     */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3813
                    return false;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3814
                }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3815
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3816
                if (count == run.length) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3817
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3818
                    /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3819
                     * Increase capacity of index array.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3820
                     */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3821
                    run = Arrays.copyOf(run, count << 1);
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3822
                }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3823
            }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3824
            run[count] = (last = k);
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3825
        }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3826
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3827
        /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3828
         * Merge runs of highly structured array.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3829
         */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3830
        if (count > 1) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3831
            double[] b; int offset = low;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3832
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3833
            if (sorter == null || (b = (double[]) sorter.b) == null) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3834
                b = new double[size];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3835
            } else {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3836
                offset = sorter.offset;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3837
            }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3838
            mergeRuns(a, b, offset, 1, sorter != null, run, 0, count);
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3839
        }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3840
        return true;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3841
    }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3842
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3843
    /**
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3844
     * Merges the specified runs.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3845
     *
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3846
     * @param a the source array
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3847
     * @param b the temporary buffer used in merging
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3848
     * @param offset the start index in the source, inclusive
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3849
     * @param aim specifies merging: to source ( > 0), buffer ( < 0) or any ( == 0)
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3850
     * @param parallel indicates whether merging is performed in parallel
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3851
     * @param run the start indexes of the runs, inclusive
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3852
     * @param lo the start index of the first run, inclusive
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3853
     * @param hi the start index of the last run, inclusive
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3854
     * @return the destination where runs are merged
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3855
     */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3856
    private static double[] mergeRuns(double[] a, double[] b, int offset,
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3857
            int aim, boolean parallel, int[] run, int lo, int hi) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3858
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3859
        if (hi - lo == 1) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3860
            if (aim >= 0) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3861
                return a;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3862
            }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3863
            for (int i = run[hi], j = i - offset, low = run[lo]; i > low;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3864
                b[--j] = a[--i]
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3865
            );
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3866
            return b;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3867
        }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3868
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3869
        /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3870
         * Split into approximately equal parts.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3871
         */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3872
        int mi = lo, rmi = (run[lo] + run[hi]) >>> 1;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3873
        while (run[++mi + 1] <= rmi);
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3874
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3875
        /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3876
         * Merge the left and right parts.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3877
         */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3878
        double[] a1, a2;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3879
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3880
        if (parallel && hi - lo > MIN_RUN_COUNT) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3881
            RunMerger merger = new RunMerger(a, b, offset, 0, run, mi, hi).forkMe();
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3882
            a1 = mergeRuns(a, b, offset, -aim, true, run, lo, mi);
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3883
            a2 = (double[]) merger.getDestination();
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3884
        } else {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3885
            a1 = mergeRuns(a, b, offset, -aim, false, run, lo, mi);
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3886
            a2 = mergeRuns(a, b, offset,    0, false, run, mi, hi);
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3887
        }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3888
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3889
        double[] dst = a1 == a ? b : a;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3890
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3891
        int k   = a1 == a ? run[lo] - offset : run[lo];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3892
        int lo1 = a1 == b ? run[lo] - offset : run[lo];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3893
        int hi1 = a1 == b ? run[mi] - offset : run[mi];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3894
        int lo2 = a2 == b ? run[mi] - offset : run[mi];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3895
        int hi2 = a2 == b ? run[hi] - offset : run[hi];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3896
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3897
        if (parallel) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3898
            new Merger(null, dst, k, a1, lo1, hi1, a2, lo2, hi2).invoke();
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3899
        } else {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3900
            mergeParts(null, dst, k, a1, lo1, hi1, a2, lo2, hi2);
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3901
        }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3902
        return dst;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3903
    }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3904
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3905
    /**
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3906
     * Merges the sorted parts.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3907
     *
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3908
     * @param merger parallel context
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3909
     * @param dst the destination where parts are merged
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3910
     * @param k the start index of the destination, inclusive
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3911
     * @param a1 the first part
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3912
     * @param lo1 the start index of the first part, inclusive
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3913
     * @param hi1 the end index of the first part, exclusive
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3914
     * @param a2 the second part
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3915
     * @param lo2 the start index of the second part, inclusive
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3916
     * @param hi2 the end index of the second part, exclusive
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3917
     */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3918
    private static void mergeParts(Merger merger, double[] dst, int k,
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3919
            double[] a1, int lo1, int hi1, double[] a2, int lo2, int hi2) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3920
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3921
        if (merger != null && a1 == a2) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3922
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3923
            while (true) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3924
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3925
                /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3926
                 * The first part must be larger.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3927
                 */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3928
                if (hi1 - lo1 < hi2 - lo2) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3929
                    int lo = lo1; lo1 = lo2; lo2 = lo;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3930
                    int hi = hi1; hi1 = hi2; hi2 = hi;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3931
                }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3932
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3933
                /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3934
                 * Small parts will be merged sequentially.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3935
                 */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3936
                if (hi1 - lo1 < MIN_PARALLEL_MERGE_PARTS_SIZE) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3937
                    break;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3938
                }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3939
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3940
                /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3941
                 * Find the median of the larger part.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3942
                 */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3943
                int mi1 = (lo1 + hi1) >>> 1;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3944
                double key = a1[mi1];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3945
                int mi2 = hi2;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3946
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3947
                /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3948
                 * Partition the smaller part.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3949
                 */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3950
                for (int loo = lo2; loo < mi2; ) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3951
                    int t = (loo + mi2) >>> 1;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3952
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3953
                    if (key > a2[t]) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3954
                        loo = t + 1;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3955
                    } else {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3956
                        mi2 = t;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3957
                    }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3958
                }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3959
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3960
                int d = mi2 - lo2 + mi1 - lo1;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3961
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3962
                /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3963
                 * Merge the right sub-parts in parallel.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3964
                 */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3965
                merger.forkMerger(dst, k + d, a1, mi1, hi1, a2, mi2, hi2);
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3966
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3967
                /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3968
                 * Process the sub-left parts.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3969
                 */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3970
                hi1 = mi1;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3971
                hi2 = mi2;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3972
            }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3973
        }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3974
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3975
        /*
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3976
         * Merge small parts sequentially.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3977
         */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3978
        while (lo1 < hi1 && lo2 < hi2) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3979
            dst[k++] = a1[lo1] < a2[lo2] ? a1[lo1++] : a2[lo2++];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3980
        }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3981
        if (dst != a1 || k < lo1) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3982
            while (lo1 < hi1) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3983
                dst[k++] = a1[lo1++];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3984
            }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3985
        }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3986
        if (dst != a2 || k < lo2) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3987
            while (lo2 < hi2) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3988
                dst[k++] = a2[lo2++];
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3989
            }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3990
        }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3991
    }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3992
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3993
// [class]
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3994
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3995
    /**
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3996
     * This class implements parallel sorting.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3997
     */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3998
    private static final class Sorter extends CountedCompleter<Void> {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  3999
        private static final long serialVersionUID = 20180818L;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  4000
        private final Object a, b;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  4001
        private final int low, size, offset, depth;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  4002
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  4003
        private Sorter(CountedCompleter<?> parent,
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  4004
                Object a, Object b, int low, int size, int offset, int depth) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  4005
            super(parent);
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  4006
            this.a = a;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  4007
            this.b = b;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  4008
            this.low = low;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  4009
            this.size = size;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  4010
            this.offset = offset;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  4011
            this.depth = depth;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  4012
        }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  4013
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  4014
        @Override
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  4015
        public final void compute() {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  4016
            if (depth < 0) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  4017
                setPendingCount(2);
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  4018
                int half = size >> 1;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  4019
                new Sorter(this, b, a, low, half, offset, depth + 1).fork();
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  4020
                new Sorter(this, b, a, low + half, size - half, offset, depth + 1).compute();
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  4021
            } else {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  4022
                if (a instanceof int[]) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  4023
                    sort(this, (int[]) a, depth, low, low + size);
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  4024
                } else if (a instanceof long[]) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  4025
                    sort(this, (long[]) a, depth, low, low + size);
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  4026
                } else if (a instanceof float[]) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  4027
                    sort(this, (float[]) a, depth, low, low + size);
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  4028
                } else if (a instanceof double[]) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  4029
                    sort(this, (double[]) a, depth, low, low + size);
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  4030
                } else {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  4031
                    throw new IllegalArgumentException(
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  4032
                        "Unknown type of array: " + a.getClass().getName());
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  4033
                }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  4034
            }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  4035
            tryComplete();
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  4036
        }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  4037
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  4038
        @Override
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  4039
        public final void onCompletion(CountedCompleter<?> caller) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  4040
            if (depth < 0) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  4041
                int mi = low + (size >> 1);
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  4042
                boolean src = (depth & 1) == 0;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  4043
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  4044
                new Merger(null,
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  4045
                    a,
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  4046
                    src ? low : low - offset,
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  4047
                    b,
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  4048
                    src ? low - offset : low,
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  4049
                    src ? mi - offset : mi,
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  4050
                    b,
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  4051
                    src ? mi - offset : mi,
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  4052
                    src ? low + size - offset : low + size
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  4053
                ).invoke();
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  4054
            }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  4055
        }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  4056
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  4057
        private void forkSorter(int depth, int low, int high) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  4058
            addToPendingCount(1);
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  4059
            Object a = this.a; // Use local variable for performance
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  4060
            new Sorter(this, a, b, low, high - low, offset, depth).fork();
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  4061
        }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  4062
    }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  4063
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  4064
    /**
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  4065
     * This class implements parallel merging.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  4066
     */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  4067
    private static final class Merger extends CountedCompleter<Void> {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  4068
        private static final long serialVersionUID = 20180818L;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  4069
        private final Object dst, a1, a2;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  4070
        private final int k, lo1, hi1, lo2, hi2;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  4071
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  4072
        private Merger(CountedCompleter<?> parent, Object dst, int k,
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  4073
                Object a1, int lo1, int hi1, Object a2, int lo2, int hi2) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  4074
            super(parent);
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  4075
            this.dst = dst;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  4076
            this.k = k;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  4077
            this.a1 = a1;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  4078
            this.lo1 = lo1;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  4079
            this.hi1 = hi1;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  4080
            this.a2 = a2;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  4081
            this.lo2 = lo2;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  4082
            this.hi2 = hi2;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  4083
        }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  4084
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  4085
        @Override
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  4086
        public final void compute() {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  4087
            if (dst instanceof int[]) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  4088
                mergeParts(this, (int[]) dst, k,
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  4089
                    (int[]) a1, lo1, hi1, (int[]) a2, lo2, hi2);
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  4090
            } else if (dst instanceof long[]) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  4091
                mergeParts(this, (long[]) dst, k,
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  4092
                    (long[]) a1, lo1, hi1, (long[]) a2, lo2, hi2);
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  4093
            } else if (dst instanceof float[]) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  4094
                mergeParts(this, (float[]) dst, k,
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  4095
                    (float[]) a1, lo1, hi1, (float[]) a2, lo2, hi2);
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  4096
            } else if (dst instanceof double[]) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  4097
                mergeParts(this, (double[]) dst, k,
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  4098
                    (double[]) a1, lo1, hi1, (double[]) a2, lo2, hi2);
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  4099
            } else {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  4100
                throw new IllegalArgumentException(
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  4101
                    "Unknown type of array: " + dst.getClass().getName());
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  4102
            }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  4103
            propagateCompletion();
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  4104
        }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  4105
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  4106
        private void forkMerger(Object dst, int k,
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  4107
                Object a1, int lo1, int hi1, Object a2, int lo2, int hi2) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  4108
            addToPendingCount(1);
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  4109
            new Merger(this, dst, k, a1, lo1, hi1, a2, lo2, hi2).fork();
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  4110
        }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  4111
    }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  4112
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  4113
    /**
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  4114
     * This class implements parallel merging of runs.
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  4115
     */
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  4116
    private static final class RunMerger extends RecursiveTask<Object> {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  4117
        private static final long serialVersionUID = 20180818L;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  4118
        private final Object a, b;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  4119
        private final int[] run;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  4120
        private final int offset, aim, lo, hi;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  4121
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  4122
        private RunMerger(Object a, Object b, int offset,
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  4123
                int aim, int[] run, int lo, int hi) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  4124
            this.a = a;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  4125
            this.b = b;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  4126
            this.offset = offset;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  4127
            this.aim = aim;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  4128
            this.run = run;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  4129
            this.lo = lo;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  4130
            this.hi = hi;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  4131
        }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  4132
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  4133
        @Override
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  4134
        protected final Object compute() {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  4135
            if (a instanceof int[]) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  4136
                return mergeRuns((int[]) a, (int[]) b, offset, aim, true, run, lo, hi);
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  4137
            }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  4138
            if (a instanceof long[]) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  4139
                return mergeRuns((long[]) a, (long[]) b, offset, aim, true, run, lo, hi);
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  4140
            }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  4141
            if (a instanceof float[]) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  4142
                return mergeRuns((float[]) a, (float[]) b, offset, aim, true, run, lo, hi);
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  4143
            }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  4144
            if (a instanceof double[]) {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  4145
                return mergeRuns((double[]) a, (double[]) b, offset, aim, true, run, lo, hi);
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  4146
            }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  4147
            throw new IllegalArgumentException(
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  4148
                "Unknown type of array: " + a.getClass().getName());
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  4149
        }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  4150
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  4151
        private RunMerger forkMe() {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  4152
            fork();
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  4153
            return this;
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  4154
        }
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  4155
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  4156
        private Object getDestination() {
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  4157
            join();
8910b995a2ee 8226297: Dual-pivot quicksort improvements
bchristi
parents: 47216
diff changeset
  4158
            return getRawResult();
4170
a94a6faf44e6 6880672: Replace quicksort in java.util.Arrays with dual-pivot implementation
alanb
parents:
diff changeset
  4159
        }
4233
9b594a48d0f4 6899694: Dual-pivot quicksort improvements
alanb
parents: 4177
diff changeset
  4160
    }
4170
a94a6faf44e6 6880672: Replace quicksort in java.util.Arrays with dual-pivot implementation
alanb
parents:
diff changeset
  4161
}