Merge pull request #106661 from KirbyRider1337/dont-compare-the-same-item-with-itself

Prevent comparison of items with themselves while partitioning sort arrays
This commit is contained in:
Thaddeus Crews 2025-05-22 12:14:58 -05:00
commit c3c3657a0d
No known key found for this signature in database
GPG key ID: 8C6E5FEB5FC03CCC

View file

@ -54,21 +54,24 @@ class SortArray {
public:
Comparator compare;
inline const T &median_of_3(const T &a, const T &b, const T &c) const {
inline int64_t median_of_3_index(const T *p_ptr, int64_t a_index, int64_t b_index, int64_t c_index) const {
const T &a = p_ptr[a_index];
const T &b = p_ptr[b_index];
const T &c = p_ptr[c_index];
if (compare(a, b)) {
if (compare(b, c)) {
return b;
return b_index;
} else if (compare(a, c)) {
return c;
return c_index;
} else {
return a;
return a_index;
}
} else if (compare(a, c)) {
return a;
return a_index;
} else if (compare(b, c)) {
return c;
return c_index;
} else {
return b;
return b_index;
}
}
@ -162,26 +165,27 @@ public:
}
}
inline int64_t partitioner(int64_t p_first, int64_t p_last, T p_pivot, T *p_array) const {
inline int64_t partitioner(int64_t p_first, int64_t p_last, int64_t p_pivot, T *p_array) const {
const int64_t unmodified_first = p_first;
const int64_t unmodified_last = p_last;
const T &pivot_element = p_array[p_pivot];
while (true) {
while (compare(p_array[p_first], p_pivot)) {
while (p_first != p_pivot && compare(p_array[p_first], pivot_element)) {
if constexpr (Validate) {
ERR_BAD_COMPARE(p_first == unmodified_last - 1);
}
p_first++;
}
p_last--;
while (compare(p_pivot, p_array[p_last])) {
while (p_last != p_pivot && compare(pivot_element, p_array[p_last])) {
if constexpr (Validate) {
ERR_BAD_COMPARE(p_last == unmodified_first);
}
p_last--;
}
if (!(p_first < p_last)) {
if (p_first >= p_last) {
return p_first;
}
@ -202,10 +206,7 @@ public:
int64_t cut = partitioner(
p_first,
p_last,
median_of_3(
p_array[p_first],
p_array[p_first + (p_last - p_first) / 2],
p_array[p_last - 1]),
median_of_3_index(p_array, p_first, p_first + (p_last - p_first) / 2, p_last - 1),
p_array);
introsort(cut, p_last, p_array, p_max_depth);
@ -226,10 +227,7 @@ public:
int64_t cut = partitioner(
p_first,
p_last,
median_of_3(
p_array[p_first],
p_array[p_first + (p_last - p_first) / 2],
p_array[p_last - 1]),
median_of_3_index(p_array, p_first, p_first + (p_last - p_first) / 2, p_last - 1),
p_array);
if (cut <= p_nth) {