Skip to content
Closed
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 23 additions & 9 deletions contracts/utils/Arrays.sol
Original file line number Diff line number Diff line change
Expand Up @@ -112,29 +112,43 @@ library Arrays {
* IMPORTANT: Memory locations between `begin` and `end` are not validated/zeroed. This function should
* be used only if the limits are within a memory array.
*/
function _quickSort(uint256 begin, uint256 end, function(uint256, uint256) pure returns (bool) comp) private pure {
unchecked {
function _quickSort(
uint256 begin,
uint256 end,
function(uint256, uint256) pure returns (bool) comp
) private pure {
unchecked {
while (true) {
if (end - begin < 0x40) return;

// Use first element as pivot
uint256 pivot = _mload(begin);
// Position where the pivot should be at the end of the loop
uint256 pos = begin;

for (uint256 it = begin + 0x20; it < end; it += 0x20) {
if (comp(_mload(it), pivot)) {
// If the value stored at the iterator's position comes before the pivot, we increment the
// position of the pivot and move the value there.
pos += 0x20;
_swap(pos, it);
}
}

_swap(begin, pos); // Swap pivot into place
_quickSort(begin, pos, comp); // Sort the left side of the pivot
_quickSort(pos + 0x20, end, comp); // Sort the right side of the pivot
_swap(begin, pos);

// ────────────────────────────────────────────────────────────────
// This is the actual fix: recurse ONLY on the SMALLER side
// ────────────────────────────────────────────────────────────────
if (pos - begin < end - (pos + 0x20)) {
// left smaller → recurse left, loop on right
_quickSort(begin, pos, comp);
begin = pos + 0x20;
} else {
// right smaller or equal → recurse right, loop on left
_quickSort(pos + 0x20, end, comp);
end = pos;
}
// loop continues with updated bounds → no second recursion
}
}
}

/**
* @dev Pointer to the memory location of the first element of `array`.
Expand Down
Loading