partially sorts a slice by shifting several out-of-order elements around.
returns true if the slice is sorted at the end. This function is O(n) worst-case.
fn partialInsertionSort(a: usize, b: usize, context: anytype) bool
fn partialInsertionSort(a: usize, b: usize, context: anytype) bool {
@branchHint(.cold);
// maximum number of adjacent out-of-order pairs that will get shifted
const max_steps = 5;
// if the slice is shorter than this, don't shift any elements
const shortest_shifting = 50;
var i = a + 1;
for (0..max_steps) |_| {
// find the next pair of adjacent out-of-order elements.
while (i < b and !context.lessThan(i, i - 1)) i += 1;
// are we done?
if (i == b) return true;
// don't shift elements on short arrays, that has a performance cost.
if (b - a < shortest_shifting) return false;
// swap the found pair of elements. This puts them in correct order.
context.swap(i, i - 1);
// shift the smaller element to the left.
if (i - a >= 2) {
var j = i - 1;
while (j > a) : (j -= 1) {
if (!context.lessThan(j, j - 1)) break;
context.swap(j, j - 1);
}
}
// shift the greater element to the right.
if (b - i >= 2) {
var j = i + 1;
while (j < b) : (j += 1) {
if (!context.lessThan(j, j - 1)) break;
context.swap(j, j - 1);
}
}
}
return false;
}