mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-27 23:04:50 +02:00
8203864: Execution error in Java's Timsort
Reviewed-by: martin, psandoz, forax
This commit is contained in:
parent
abffccb329
commit
3afeb2cb48
2 changed files with 20 additions and 12 deletions
|
@ -305,7 +305,7 @@ class ComparableTimSort {
|
||||||
* @param a the array in which a run is to be counted and possibly reversed
|
* @param a the array in which a run is to be counted and possibly reversed
|
||||||
* @param lo index of the first element in the run
|
* @param lo index of the first element in the run
|
||||||
* @param hi index after the last element that may be contained in the run.
|
* @param hi index after the last element that may be contained in the run.
|
||||||
It is required that {@code lo < hi}.
|
* It is required that {@code lo < hi}.
|
||||||
* @return the length of the run beginning at the specified position in
|
* @return the length of the run beginning at the specified position in
|
||||||
* the specified array
|
* the specified array
|
||||||
*/
|
*/
|
||||||
|
@ -394,19 +394,23 @@ class ComparableTimSort {
|
||||||
* This method is called each time a new run is pushed onto the stack,
|
* This method is called each time a new run is pushed onto the stack,
|
||||||
* so the invariants are guaranteed to hold for i < stackSize upon
|
* so the invariants are guaranteed to hold for i < stackSize upon
|
||||||
* entry to the method.
|
* entry to the method.
|
||||||
|
*
|
||||||
|
* Thanks to Stijn de Gouw, Jurriaan Rot, Frank S. de Boer,
|
||||||
|
* Richard Bubel and Reiner Hahnle, this is fixed with respect to
|
||||||
|
* the analysis in "On the Worst-Case Complexity of TimSort" by
|
||||||
|
* Nicolas Auger, Vincent Jug, Cyril Nicaud, and Carine Pivoteau.
|
||||||
*/
|
*/
|
||||||
private void mergeCollapse() {
|
private void mergeCollapse() {
|
||||||
while (stackSize > 1) {
|
while (stackSize > 1) {
|
||||||
int n = stackSize - 2;
|
int n = stackSize - 2;
|
||||||
if (n > 0 && runLen[n-1] <= runLen[n] + runLen[n+1]) {
|
if (n > 0 && runLen[n-1] <= runLen[n] + runLen[n+1] ||
|
||||||
|
n > 1 && runLen[n-2] <= runLen[n] + runLen[n-1]) {
|
||||||
if (runLen[n - 1] < runLen[n + 1])
|
if (runLen[n - 1] < runLen[n + 1])
|
||||||
n--;
|
n--;
|
||||||
mergeAt(n);
|
} else if (n < 0 || runLen[n] > runLen[n + 1]) {
|
||||||
} else if (runLen[n] <= runLen[n + 1]) {
|
|
||||||
mergeAt(n);
|
|
||||||
} else {
|
|
||||||
break; // Invariant is established
|
break; // Invariant is established
|
||||||
}
|
}
|
||||||
|
mergeAt(n);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -339,7 +339,7 @@ class TimSort<T> {
|
||||||
* @param a the array in which a run is to be counted and possibly reversed
|
* @param a the array in which a run is to be counted and possibly reversed
|
||||||
* @param lo index of the first element in the run
|
* @param lo index of the first element in the run
|
||||||
* @param hi index after the last element that may be contained in the run.
|
* @param hi index after the last element that may be contained in the run.
|
||||||
It is required that {@code lo < hi}.
|
* It is required that {@code lo < hi}.
|
||||||
* @param c the comparator to used for the sort
|
* @param c the comparator to used for the sort
|
||||||
* @return the length of the run beginning at the specified position in
|
* @return the length of the run beginning at the specified position in
|
||||||
* the specified array
|
* the specified array
|
||||||
|
@ -429,19 +429,23 @@ class TimSort<T> {
|
||||||
* This method is called each time a new run is pushed onto the stack,
|
* This method is called each time a new run is pushed onto the stack,
|
||||||
* so the invariants are guaranteed to hold for i < stackSize upon
|
* so the invariants are guaranteed to hold for i < stackSize upon
|
||||||
* entry to the method.
|
* entry to the method.
|
||||||
|
*
|
||||||
|
* Thanks to Stijn de Gouw, Jurriaan Rot, Frank S. de Boer,
|
||||||
|
* Richard Bubel and Reiner Hahnle, this is fixed with respect to
|
||||||
|
* the analysis in "On the Worst-Case Complexity of TimSort" by
|
||||||
|
* Nicolas Auger, Vincent Jug, Cyril Nicaud, and Carine Pivoteau.
|
||||||
*/
|
*/
|
||||||
private void mergeCollapse() {
|
private void mergeCollapse() {
|
||||||
while (stackSize > 1) {
|
while (stackSize > 1) {
|
||||||
int n = stackSize - 2;
|
int n = stackSize - 2;
|
||||||
if (n > 0 && runLen[n-1] <= runLen[n] + runLen[n+1]) {
|
if (n > 0 && runLen[n-1] <= runLen[n] + runLen[n+1] ||
|
||||||
|
n > 1 && runLen[n-2] <= runLen[n] + runLen[n-1]) {
|
||||||
if (runLen[n - 1] < runLen[n + 1])
|
if (runLen[n - 1] < runLen[n + 1])
|
||||||
n--;
|
n--;
|
||||||
mergeAt(n);
|
} else if (n < 0 || runLen[n] > runLen[n + 1]) {
|
||||||
} else if (runLen[n] <= runLen[n + 1]) {
|
|
||||||
mergeAt(n);
|
|
||||||
} else {
|
|
||||||
break; // Invariant is established
|
break; // Invariant is established
|
||||||
}
|
}
|
||||||
|
mergeAt(n);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue