Skip to content

Commit

Permalink
🥢 Edit MinHeapLib comments (#798)
Browse files Browse the repository at this point in the history
  • Loading branch information
Vectorized authored Jan 17, 2024
1 parent 5ddc201 commit c80be63
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 34 deletions.
16 changes: 8 additions & 8 deletions .gas-snapshot
Original file line number Diff line number Diff line change
Expand Up @@ -844,17 +844,17 @@ MetadataReaderLibTest:testReadStringTruncated(uint256) (runs: 256, μ: 775902, ~
MetadataReaderLibTest:testReadUint() (gas: 542217)
MetadataReaderLibTest:testReadUint(uint256) (runs: 256, μ: 22765, ~: 23854)
MetadataReaderLibTest:test__codesize() (gas: 8645)
MinHeapLibTest:testHeapEnqueue(uint256) (runs: 256, μ: 186631, ~: 182615)
MinHeapLibTest:testHeapEnqueue2(uint256) (runs: 256, μ: 609201, ~: 426081)
MinHeapLibTest:testHeapEnqueue(uint256) (runs: 256, μ: 189448, ~: 190219)
MinHeapLibTest:testHeapEnqueue2(uint256) (runs: 256, μ: 622997, ~: 473374)
MinHeapLibTest:testHeapEnqueueGas() (gas: 856319)
MinHeapLibTest:testHeapPSiftTrick(uint256,uint256,uint256) (runs: 256, μ: 717, ~: 877)
MinHeapLibTest:testHeapPushAndPop(uint256) (runs: 256, μ: 103685, ~: 99755)
MinHeapLibTest:testHeapPushPop(uint256) (runs: 256, μ: 237955, ~: 233915)
MinHeapLibTest:testHeapReplace(uint256) (runs: 256, μ: 296075, ~: 291888)
MinHeapLibTest:testHeapPSiftTrick(uint256,uint256,uint256) (runs: 256, μ: 714, ~: 880)
MinHeapLibTest:testHeapPushAndPop(uint256) (runs: 256, μ: 103491, ~: 99482)
MinHeapLibTest:testHeapPushPop(uint256) (runs: 256, μ: 242453, ~: 243562)
MinHeapLibTest:testHeapReplace(uint256) (runs: 256, μ: 290302, ~: 285311)
MinHeapLibTest:testHeapRoot(uint256) (runs: 256, μ: 5232, ~: 5232)
MinHeapLibTest:testHeapSmallest(uint256) (runs: 256, μ: 1648506, ~: 1287956)
MinHeapLibTest:testHeapSmallest(uint256) (runs: 256, μ: 1685450, ~: 1288158)
MinHeapLibTest:testHeapSmallestGas() (gas: 49973111)
MinHeapLibTest:test__codesize() (gas: 8139)
MinHeapLibTest:test__codesize() (gas: 8140)
MulticallableTest:testMulticallableBenchmark() (gas: 29588)
MulticallableTest:testMulticallableOriginalBenchmark() (gas: 38849)
MulticallableTest:testMulticallablePreservesMsgSender() (gas: 11193)
Expand Down
45 changes: 20 additions & 25 deletions src/utils/MinHeapLib.sol
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ library MinHeapLib {
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

// Tips:
// - To use as a max-heap, bitwise negate the values (e.g. `heap.push(~x)`).
// - If use on tuples, pack the tuple values into a single integer.
// - To use as a max-heap, bitwise negate the input and output values (e.g. `heap.push(~x)`).
// - To use on tuples, pack the tuple values into a single integer.
// - To use on signed integers, convert the signed integers into
// their ordered unsigned counterparts via `uint256(x) + (1 << 255)`.

Expand Down Expand Up @@ -168,25 +168,23 @@ library MinHeapLib {
/// @solidity memory-safe-assembly
assembly {
let n := sload(heap.slot)
// Compute the array storage slot offset.
mstore(0x00, heap.slot)
let sOffset := keccak256(0x00, 0x20)

let sOffset := keccak256(0x00, 0x20) // Array storage slot offset.
let pos := 0
let childPos := not(0)
// Operations are ordered from most likely usage to least likely usage.
for {} 1 {
mstore(0x00, 0xa6ca772e) // Store the function selector of `HeapIsEmpty()`.
revert(0x1c, 0x04) // Revert with (offset, size).
mstore(0x00, 0xa6ca772e) // `HeapIsEmpty()`.
revert(0x1c, 0x04)
} {
// `enqueue`.
// Mode: `enqueue`.
if iszero(mode) {
if iszero(maxLength) { continue }
// If queue is not full.
if iszero(eq(n, maxLength)) {
// If queue is not full.
success := 1
// Increment and update the length.
pos := n
// Increment and update the length.
sstore(heap.slot, add(pos, 1))
childPos := add(childPos, childPos)
break
Expand All @@ -199,14 +197,14 @@ library MinHeapLib {
popped := r
break
}
// `replace`.
// Mode: `replace`.
if eq(mode, 1) {
if iszero(n) { continue }
popped := sload(sOffset)
childPos := 1
break
}
// `pushPop`.
// Mode: `pushPop`.
if eq(mode, 2) {
popped := value
if iszero(n) { break }
Expand All @@ -216,7 +214,7 @@ library MinHeapLib {
childPos := 1
break
}
// `pop`.
// Mode: `pop`.
if eq(mode, 3) {
if iszero(n) { continue }
// Decrement and update the length.
Expand All @@ -230,16 +228,14 @@ library MinHeapLib {
childPos := 1
break
}
// `push`.
{
// Increment and update the length.
pos := n
sstore(heap.slot, add(pos, 1))
childPos := add(childPos, childPos)
break
}
// Mode: `push`.
// Increment and update the length.
pos := n
sstore(heap.slot, add(pos, 1))
childPos := add(childPos, childPos)
break
}

// Siftup.
for {} lt(childPos, n) {} {
let child := sload(add(sOffset, childPos))
let rightPos := add(childPos, 1)
Expand All @@ -252,16 +248,15 @@ library MinHeapLib {
pos := rightPos
childPos := add(shl(1, pos), 1)
}

// Siftdown.
for {} pos {} {
let parentPos := shr(1, sub(pos, 1))
let parent := sload(add(sOffset, parentPos))
if iszero(lt(value, parent)) { break }
sstore(add(sOffset, pos), parent)
pos := parentPos
}

// If `childPos` is not `not(0)`.
// If `childPos` has been changed from `not(0)`.
if add(childPos, 1) { sstore(add(sOffset, pos), value) }
}
}
Expand Down
2 changes: 1 addition & 1 deletion test/MinHeapLib.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ contract MinHeapLibTest is SoladyTest {
let child := pValue(sOffset, childPos)
let rightPos := add(childPos, 1)
let right := pValue(sOffset, rightPos)
if iszero(and(lt(rightPos, n), iszero(lt(child, right)))) {
if or(iszero(lt(rightPos, n)), lt(child, right)) {
right := child
rightPos := childPos
}
Expand Down

0 comments on commit c80be63

Please sign in to comment.