Skip to content

Commit d20b9e3

Browse files
Amxxernestognw
andauthored
Add paginated version of EnumerableSet.values() and EnumerableMap.keys() (#5713)
Co-authored-by: ernestognw <[email protected]>
1 parent f45e915 commit d20b9e3

File tree

10 files changed

+472
-4
lines changed

10 files changed

+472
-4
lines changed

.changeset/fine-frogs-bake.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'openzeppelin-solidity': minor
3+
---
4+
5+
`EnumerableMap`: Add `keys(uint256,uint256)` that returns a subset (slice) of the keys in the map.

.changeset/hot-grapes-lie.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'openzeppelin-solidity': minor
3+
---
4+
5+
`EnumerableSet`: Add `values(uint256,uint256)` that returns a subset (slice) of the values in the set.

contracts/utils/structs/EnumerableMap.sol

Lines changed: 194 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@ library EnumerableMap {
164164
}
165165

166166
/**
167-
* @dev Return the an array containing all the keys
167+
* @dev Returns an array containing all the keys
168168
*
169169
* WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
170170
* to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
@@ -175,6 +175,22 @@ library EnumerableMap {
175175
return map._keys.values();
176176
}
177177

178+
/**
179+
* @dev Returns an array containing a slice of the keys
180+
*
181+
* WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
182+
* to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
183+
* this function has an unbounded cost, and using it as part of a state-changing function may render the function
184+
* uncallable if the map grows to a point where copying to memory consumes too much gas to fit in a block.
185+
*/
186+
function keys(
187+
Bytes32ToBytes32Map storage map,
188+
uint256 start,
189+
uint256 end
190+
) internal view returns (bytes32[] memory) {
191+
return map._keys.values(start, end);
192+
}
193+
178194
// UintToUintMap
179195

180196
struct UintToUintMap {
@@ -278,6 +294,25 @@ library EnumerableMap {
278294
return result;
279295
}
280296

297+
/**
298+
* @dev Return the an array containing a slice of the keys
299+
*
300+
* WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
301+
* to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
302+
* this function has an unbounded cost, and using it as part of a state-changing function may render the function
303+
* uncallable if the map grows to a point where copying to memory consumes too much gas to fit in a block.
304+
*/
305+
function keys(UintToUintMap storage map, uint256 start, uint256 end) internal view returns (uint256[] memory) {
306+
bytes32[] memory store = keys(map._inner, start, end);
307+
uint256[] memory result;
308+
309+
assembly ("memory-safe") {
310+
result := store
311+
}
312+
313+
return result;
314+
}
315+
281316
// UintToAddressMap
282317

283318
struct UintToAddressMap {
@@ -381,6 +416,25 @@ library EnumerableMap {
381416
return result;
382417
}
383418

419+
/**
420+
* @dev Return the an array containing a slice of the keys
421+
*
422+
* WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
423+
* to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
424+
* this function has an unbounded cost, and using it as part of a state-changing function may render the function
425+
* uncallable if the map grows to a point where copying to memory consumes too much gas to fit in a block.
426+
*/
427+
function keys(UintToAddressMap storage map, uint256 start, uint256 end) internal view returns (uint256[] memory) {
428+
bytes32[] memory store = keys(map._inner, start, end);
429+
uint256[] memory result;
430+
431+
assembly ("memory-safe") {
432+
result := store
433+
}
434+
435+
return result;
436+
}
437+
384438
// UintToBytes32Map
385439

386440
struct UintToBytes32Map {
@@ -484,6 +538,25 @@ library EnumerableMap {
484538
return result;
485539
}
486540

541+
/**
542+
* @dev Return the an array containing a slice of the keys
543+
*
544+
* WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
545+
* to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
546+
* this function has an unbounded cost, and using it as part of a state-changing function may render the function
547+
* uncallable if the map grows to a point where copying to memory consumes too much gas to fit in a block.
548+
*/
549+
function keys(UintToBytes32Map storage map, uint256 start, uint256 end) internal view returns (uint256[] memory) {
550+
bytes32[] memory store = keys(map._inner, start, end);
551+
uint256[] memory result;
552+
553+
assembly ("memory-safe") {
554+
result := store
555+
}
556+
557+
return result;
558+
}
559+
487560
// AddressToUintMap
488561

489562
struct AddressToUintMap {
@@ -587,6 +660,25 @@ library EnumerableMap {
587660
return result;
588661
}
589662

663+
/**
664+
* @dev Return the an array containing a slice of the keys
665+
*
666+
* WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
667+
* to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
668+
* this function has an unbounded cost, and using it as part of a state-changing function may render the function
669+
* uncallable if the map grows to a point where copying to memory consumes too much gas to fit in a block.
670+
*/
671+
function keys(AddressToUintMap storage map, uint256 start, uint256 end) internal view returns (address[] memory) {
672+
bytes32[] memory store = keys(map._inner, start, end);
673+
address[] memory result;
674+
675+
assembly ("memory-safe") {
676+
result := store
677+
}
678+
679+
return result;
680+
}
681+
590682
// AddressToAddressMap
591683

592684
struct AddressToAddressMap {
@@ -690,6 +782,29 @@ library EnumerableMap {
690782
return result;
691783
}
692784

785+
/**
786+
* @dev Return the an array containing a slice of the keys
787+
*
788+
* WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
789+
* to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
790+
* this function has an unbounded cost, and using it as part of a state-changing function may render the function
791+
* uncallable if the map grows to a point where copying to memory consumes too much gas to fit in a block.
792+
*/
793+
function keys(
794+
AddressToAddressMap storage map,
795+
uint256 start,
796+
uint256 end
797+
) internal view returns (address[] memory) {
798+
bytes32[] memory store = keys(map._inner, start, end);
799+
address[] memory result;
800+
801+
assembly ("memory-safe") {
802+
result := store
803+
}
804+
805+
return result;
806+
}
807+
693808
// AddressToBytes32Map
694809

695810
struct AddressToBytes32Map {
@@ -793,6 +908,29 @@ library EnumerableMap {
793908
return result;
794909
}
795910

911+
/**
912+
* @dev Return the an array containing a slice of the keys
913+
*
914+
* WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
915+
* to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
916+
* this function has an unbounded cost, and using it as part of a state-changing function may render the function
917+
* uncallable if the map grows to a point where copying to memory consumes too much gas to fit in a block.
918+
*/
919+
function keys(
920+
AddressToBytes32Map storage map,
921+
uint256 start,
922+
uint256 end
923+
) internal view returns (address[] memory) {
924+
bytes32[] memory store = keys(map._inner, start, end);
925+
address[] memory result;
926+
927+
assembly ("memory-safe") {
928+
result := store
929+
}
930+
931+
return result;
932+
}
933+
796934
// Bytes32ToUintMap
797935

798936
struct Bytes32ToUintMap {
@@ -896,6 +1034,25 @@ library EnumerableMap {
8961034
return result;
8971035
}
8981036

1037+
/**
1038+
* @dev Return the an array containing a slice of the keys
1039+
*
1040+
* WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
1041+
* to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
1042+
* this function has an unbounded cost, and using it as part of a state-changing function may render the function
1043+
* uncallable if the map grows to a point where copying to memory consumes too much gas to fit in a block.
1044+
*/
1045+
function keys(Bytes32ToUintMap storage map, uint256 start, uint256 end) internal view returns (bytes32[] memory) {
1046+
bytes32[] memory store = keys(map._inner, start, end);
1047+
bytes32[] memory result;
1048+
1049+
assembly ("memory-safe") {
1050+
result := store
1051+
}
1052+
1053+
return result;
1054+
}
1055+
8991056
// Bytes32ToAddressMap
9001057

9011058
struct Bytes32ToAddressMap {
@@ -999,6 +1156,29 @@ library EnumerableMap {
9991156
return result;
10001157
}
10011158

1159+
/**
1160+
* @dev Return the an array containing a slice of the keys
1161+
*
1162+
* WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
1163+
* to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
1164+
* this function has an unbounded cost, and using it as part of a state-changing function may render the function
1165+
* uncallable if the map grows to a point where copying to memory consumes too much gas to fit in a block.
1166+
*/
1167+
function keys(
1168+
Bytes32ToAddressMap storage map,
1169+
uint256 start,
1170+
uint256 end
1171+
) internal view returns (bytes32[] memory) {
1172+
bytes32[] memory store = keys(map._inner, start, end);
1173+
bytes32[] memory result;
1174+
1175+
assembly ("memory-safe") {
1176+
result := store
1177+
}
1178+
1179+
return result;
1180+
}
1181+
10021182
/**
10031183
* @dev Query for a nonexistent map key.
10041184
*/
@@ -1106,7 +1286,7 @@ library EnumerableMap {
11061286
}
11071287

11081288
/**
1109-
* @dev Return the an array containing all the keys
1289+
* @dev Returns an array containing all the keys
11101290
*
11111291
* WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
11121292
* to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
@@ -1116,4 +1296,16 @@ library EnumerableMap {
11161296
function keys(BytesToBytesMap storage map) internal view returns (bytes[] memory) {
11171297
return map._keys.values();
11181298
}
1299+
1300+
/**
1301+
* @dev Returns an array containing a slice of the keys
1302+
*
1303+
* WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
1304+
* to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
1305+
* this function has an unbounded cost, and using it as part of a state-changing function may render the function
1306+
* uncallable if the map grows to a point where copying to memory consumes too much gas to fit in a block.
1307+
*/
1308+
function keys(BytesToBytesMap storage map, uint256 start, uint256 end) internal view returns (bytes[] memory) {
1309+
return map._keys.values(start, end);
1310+
}
11191311
}

0 commit comments

Comments
 (0)