Skip to content

Commit b2fda31

Browse files
committed
up
1 parent a46cc63 commit b2fda31

File tree

3 files changed

+115
-112
lines changed

3 files changed

+115
-112
lines changed

.githooks/pre-push

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,6 @@
33
set -euo pipefail
44

55
if [ "${CI:-"false"}" != "true" ]; then
6-
npm run generate
6+
npm run test:generation
77
npm run lint
88
fi

contracts/utils/structs/Heap.sol

Lines changed: 78 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ library Heap {
4646
* @dev Lookup the root element of the heap.
4747
*/
4848
function peek(Uint256Heap storage self) internal view returns (uint256) {
49+
// self.data[0] will `ARRAY_ACCESS_OUT_OF_BOUNDS` panic if heap is empty.
4950
return _unsafeNodeAccess(self, self.data[0].index).value;
5051
}
5152

@@ -69,45 +70,46 @@ library Heap {
6970
Uint256Heap storage self,
7071
function(uint256, uint256) view returns (bool) comp
7172
) internal returns (uint256) {
72-
uint32 size = length(self);
73-
74-
if (size == 0) Panic.panic(Panic.EMPTY_ARRAY_POP);
75-
76-
uint32 last = size - 1; // could be unchecked (check above)
77-
78-
// get root location (in the data array) and value
79-
Uint256HeapNode storage rootNode = _unsafeNodeAccess(self, 0);
80-
uint32 rootIdx = rootNode.index;
81-
Uint256HeapNode storage rootData = _unsafeNodeAccess(self, rootIdx);
82-
Uint256HeapNode storage lastNode = _unsafeNodeAccess(self, last);
83-
uint256 rootDataValue = rootData.value;
84-
85-
// if root is not the last element of the data array (that will get pop-ed), reorder the data array.
86-
if (rootIdx != last) {
87-
// get details about the value stored in the last element of the array (that will get pop-ed)
88-
uint32 lastDataIdx = lastNode.lookup;
89-
uint256 lastDataValue = lastNode.value;
90-
// copy these values to the location of the root (that is safe, and that we no longer use)
91-
rootData.value = lastDataValue;
92-
rootData.lookup = lastDataIdx;
93-
// update the tree node that used to point to that last element (value now located where the root was)
94-
_unsafeNodeAccess(self, lastDataIdx).index = rootIdx;
95-
}
73+
unchecked {
74+
uint32 size = length(self);
75+
if (size == 0) Panic.panic(Panic.EMPTY_ARRAY_POP);
76+
77+
uint32 last = size - 1;
78+
79+
// get root location (in the data array) and value
80+
Uint256HeapNode storage rootNode = _unsafeNodeAccess(self, 0);
81+
uint32 rootIdx = rootNode.index;
82+
Uint256HeapNode storage rootData = _unsafeNodeAccess(self, rootIdx);
83+
Uint256HeapNode storage lastNode = _unsafeNodeAccess(self, last);
84+
uint256 rootDataValue = rootData.value;
85+
86+
// if root is not the last element of the data array (that will get pop-ed), reorder the data array.
87+
if (rootIdx != last) {
88+
// get details about the value stored in the last element of the array (that will get pop-ed)
89+
uint32 lastDataIdx = lastNode.lookup;
90+
uint256 lastDataValue = lastNode.value;
91+
// copy these values to the location of the root (that is safe, and that we no longer use)
92+
rootData.value = lastDataValue;
93+
rootData.lookup = lastDataIdx;
94+
// update the tree node that used to point to that last element (value now located where the root was)
95+
_unsafeNodeAccess(self, lastDataIdx).index = rootIdx;
96+
}
9697

97-
// get last leaf location (in the data array) and value
98-
uint32 lastIdx = lastNode.index;
99-
uint256 lastValue = _unsafeNodeAccess(self, lastIdx).value;
98+
// get last leaf location (in the data array) and value
99+
uint32 lastIdx = lastNode.index;
100+
uint256 lastValue = _unsafeNodeAccess(self, lastIdx).value;
100101

101-
// move the last leaf to the root, pop last leaf ...
102-
rootNode.index = lastIdx;
103-
_unsafeNodeAccess(self, lastIdx).lookup = 0;
104-
self.data.pop();
102+
// move the last leaf to the root, pop last leaf ...
103+
rootNode.index = lastIdx;
104+
_unsafeNodeAccess(self, lastIdx).lookup = 0;
105+
self.data.pop();
105106

106-
// ... and heapify
107-
_siftDown(self, last, 0, lastValue, comp);
107+
// ... and heapify
108+
_siftDown(self, last, 0, lastValue, comp);
108109

109-
// return root value
110-
return rootDataValue;
110+
// return root value
111+
return rootDataValue;
112+
}
111113
}
112114

113115
/**
@@ -132,9 +134,8 @@ library Heap {
132134
function(uint256, uint256) view returns (bool) comp
133135
) internal {
134136
uint32 size = length(self);
135-
if (size == type(uint32).max) {
136-
Panic.panic(Panic.RESOURCE_ERROR);
137-
}
137+
if (size == type(uint32).max) Panic.panic(Panic.RESOURCE_ERROR);
138+
138139
self.data.push(Uint256HeapNode({index: size, lookup: size, value: value}));
139140
_siftUp(self, size, value, comp);
140141
}
@@ -327,6 +328,7 @@ library Heap {
327328
* @dev Lookup the root element of the heap.
328329
*/
329330
function peek(Uint208Heap storage self) internal view returns (uint208) {
331+
// self.data[0] will `ARRAY_ACCESS_OUT_OF_BOUNDS` panic if heap is empty.
330332
return _unsafeNodeAccess(self, self.data[0].index).value;
331333
}
332334

@@ -350,45 +352,46 @@ library Heap {
350352
Uint208Heap storage self,
351353
function(uint256, uint256) view returns (bool) comp
352354
) internal returns (uint208) {
353-
uint24 size = length(self);
354-
355-
if (size == 0) Panic.panic(Panic.EMPTY_ARRAY_POP);
356-
357-
uint24 last = size - 1; // could be unchecked (check above)
358-
359-
// get root location (in the data array) and value
360-
Uint208HeapNode storage rootNode = _unsafeNodeAccess(self, 0);
361-
uint24 rootIdx = rootNode.index;
362-
Uint208HeapNode storage rootData = _unsafeNodeAccess(self, rootIdx);
363-
Uint208HeapNode storage lastNode = _unsafeNodeAccess(self, last);
364-
uint208 rootDataValue = rootData.value;
365-
366-
// if root is not the last element of the data array (that will get pop-ed), reorder the data array.
367-
if (rootIdx != last) {
368-
// get details about the value stored in the last element of the array (that will get pop-ed)
369-
uint24 lastDataIdx = lastNode.lookup;
370-
uint208 lastDataValue = lastNode.value;
371-
// copy these values to the location of the root (that is safe, and that we no longer use)
372-
rootData.value = lastDataValue;
373-
rootData.lookup = lastDataIdx;
374-
// update the tree node that used to point to that last element (value now located where the root was)
375-
_unsafeNodeAccess(self, lastDataIdx).index = rootIdx;
376-
}
355+
unchecked {
356+
uint24 size = length(self);
357+
if (size == 0) Panic.panic(Panic.EMPTY_ARRAY_POP);
358+
359+
uint24 last = size - 1;
360+
361+
// get root location (in the data array) and value
362+
Uint208HeapNode storage rootNode = _unsafeNodeAccess(self, 0);
363+
uint24 rootIdx = rootNode.index;
364+
Uint208HeapNode storage rootData = _unsafeNodeAccess(self, rootIdx);
365+
Uint208HeapNode storage lastNode = _unsafeNodeAccess(self, last);
366+
uint208 rootDataValue = rootData.value;
367+
368+
// if root is not the last element of the data array (that will get pop-ed), reorder the data array.
369+
if (rootIdx != last) {
370+
// get details about the value stored in the last element of the array (that will get pop-ed)
371+
uint24 lastDataIdx = lastNode.lookup;
372+
uint208 lastDataValue = lastNode.value;
373+
// copy these values to the location of the root (that is safe, and that we no longer use)
374+
rootData.value = lastDataValue;
375+
rootData.lookup = lastDataIdx;
376+
// update the tree node that used to point to that last element (value now located where the root was)
377+
_unsafeNodeAccess(self, lastDataIdx).index = rootIdx;
378+
}
377379

378-
// get last leaf location (in the data array) and value
379-
uint24 lastIdx = lastNode.index;
380-
uint208 lastValue = _unsafeNodeAccess(self, lastIdx).value;
380+
// get last leaf location (in the data array) and value
381+
uint24 lastIdx = lastNode.index;
382+
uint208 lastValue = _unsafeNodeAccess(self, lastIdx).value;
381383

382-
// move the last leaf to the root, pop last leaf ...
383-
rootNode.index = lastIdx;
384-
_unsafeNodeAccess(self, lastIdx).lookup = 0;
385-
self.data.pop();
384+
// move the last leaf to the root, pop last leaf ...
385+
rootNode.index = lastIdx;
386+
_unsafeNodeAccess(self, lastIdx).lookup = 0;
387+
self.data.pop();
386388

387-
// ... and heapify
388-
_siftDown(self, last, 0, lastValue, comp);
389+
// ... and heapify
390+
_siftDown(self, last, 0, lastValue, comp);
389391

390-
// return root value
391-
return rootDataValue;
392+
// return root value
393+
return rootDataValue;
394+
}
392395
}
393396

394397
/**
@@ -413,9 +416,8 @@ library Heap {
413416
function(uint256, uint256) view returns (bool) comp
414417
) internal {
415418
uint24 size = length(self);
416-
if (size == type(uint24).max) {
417-
Panic.panic(Panic.RESOURCE_ERROR);
418-
}
419+
if (size == type(uint24).max) Panic.panic(Panic.RESOURCE_ERROR);
420+
419421
self.data.push(Uint208HeapNode({index: size, lookup: size, value: value}));
420422
_siftUp(self, size, value, comp);
421423
}

scripts/generate/templates/Heap.js

Lines changed: 36 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ struct ${node} {
4848
* @dev Lookup the root element of the heap.
4949
*/
5050
function peek(${struct} storage self) internal view returns (${valueType}) {
51+
// self.data[0] will \`ARRAY_ACCESS_OUT_OF_BOUNDS\` panic if heap is empty.
5152
return _unsafeNodeAccess(self, self.data[0].index).value;
5253
}
5354
@@ -71,45 +72,46 @@ function pop(
7172
${struct} storage self,
7273
function(uint256, uint256) view returns (bool) comp
7374
) internal returns (${valueType}) {
74-
${indexType} size = length(self);
75-
76-
if (size == 0) Panic.panic(Panic.EMPTY_ARRAY_POP);
75+
unchecked {
76+
${indexType} size = length(self);
77+
if (size == 0) Panic.panic(Panic.EMPTY_ARRAY_POP);
7778
78-
${indexType} last = size - 1; // could be unchecked (check above)
79+
${indexType} last = size - 1;
7980
80-
// get root location (in the data array) and value
81-
${node} storage rootNode = _unsafeNodeAccess(self, 0);
82-
${indexType} rootIdx = rootNode.index;
83-
${node} storage rootData = _unsafeNodeAccess(self, rootIdx);
84-
${node} storage lastNode = _unsafeNodeAccess(self, last);
85-
${valueType} rootDataValue = rootData.value;
81+
// get root location (in the data array) and value
82+
${node} storage rootNode = _unsafeNodeAccess(self, 0);
83+
${indexType} rootIdx = rootNode.index;
84+
${node} storage rootData = _unsafeNodeAccess(self, rootIdx);
85+
${node} storage lastNode = _unsafeNodeAccess(self, last);
86+
${valueType} rootDataValue = rootData.value;
8687
87-
// if root is not the last element of the data array (that will get pop-ed), reorder the data array.
88-
if (rootIdx != last) {
89-
// get details about the value stored in the last element of the array (that will get pop-ed)
90-
${indexType} lastDataIdx = lastNode.lookup;
91-
${valueType} lastDataValue = lastNode.value;
92-
// copy these values to the location of the root (that is safe, and that we no longer use)
93-
rootData.value = lastDataValue;
94-
rootData.lookup = lastDataIdx;
95-
// update the tree node that used to point to that last element (value now located where the root was)
96-
_unsafeNodeAccess(self, lastDataIdx).index = rootIdx;
97-
}
88+
// if root is not the last element of the data array (that will get pop-ed), reorder the data array.
89+
if (rootIdx != last) {
90+
// get details about the value stored in the last element of the array (that will get pop-ed)
91+
${indexType} lastDataIdx = lastNode.lookup;
92+
${valueType} lastDataValue = lastNode.value;
93+
// copy these values to the location of the root (that is safe, and that we no longer use)
94+
rootData.value = lastDataValue;
95+
rootData.lookup = lastDataIdx;
96+
// update the tree node that used to point to that last element (value now located where the root was)
97+
_unsafeNodeAccess(self, lastDataIdx).index = rootIdx;
98+
}
9899
99-
// get last leaf location (in the data array) and value
100-
${indexType} lastIdx = lastNode.index;
101-
${valueType} lastValue = _unsafeNodeAccess(self, lastIdx).value;
100+
// get last leaf location (in the data array) and value
101+
${indexType} lastIdx = lastNode.index;
102+
${valueType} lastValue = _unsafeNodeAccess(self, lastIdx).value;
102103
103-
// move the last leaf to the root, pop last leaf ...
104-
rootNode.index = lastIdx;
105-
_unsafeNodeAccess(self, lastIdx).lookup = 0;
106-
self.data.pop();
104+
// move the last leaf to the root, pop last leaf ...
105+
rootNode.index = lastIdx;
106+
_unsafeNodeAccess(self, lastIdx).lookup = 0;
107+
self.data.pop();
107108
108-
// ... and heapify
109-
_siftDown(self, last, 0, lastValue, comp);
109+
// ... and heapify
110+
_siftDown(self, last, 0, lastValue, comp);
110111
111-
// return root value
112-
return rootDataValue;
112+
// return root value
113+
return rootDataValue;
114+
}
113115
}
114116
115117
/**
@@ -134,9 +136,8 @@ function insert(
134136
function(uint256, uint256) view returns (bool) comp
135137
) internal {
136138
${indexType} size = length(self);
137-
if (size == type(${indexType}).max) {
138-
Panic.panic(Panic.RESOURCE_ERROR);
139-
}
139+
if (size == type(${indexType}).max) Panic.panic(Panic.RESOURCE_ERROR);
140+
140141
self.data.push(${struct}Node({index: size, lookup: size, value: value}));
141142
_siftUp(self, size, value, comp);
142143
}

0 commit comments

Comments
 (0)