diff --git a/contracts/utils/structs/EnumerableSet.sol b/contracts/utils/structs/EnumerableSet.sol index 6df060b55..425876d19 100644 --- a/contracts/utils/structs/EnumerableSet.sol +++ b/contracts/utils/structs/EnumerableSet.sol @@ -51,9 +51,9 @@ library EnumerableSet { struct Set { // Storage of set values bytes32[] _values; - // Position of the value in the `values` array, plus 1 because index 0 - // means a value is not in the set. - mapping(bytes32 value => uint256) _indexes; + // Position is the index of the value in the `values` array plus 1. + // Position 0 is used to mean a value is not in the set. + mapping(bytes32 value => uint256) _positions; } /** @@ -67,7 +67,7 @@ library EnumerableSet { set._values.push(value); // The value is stored at length-1, but we add 1 to all indexes // and use 0 as a sentinel value - set._indexes[value] = set._values.length; + set._positions[value] = set._values.length; return true; } else { return false; @@ -81,32 +81,32 @@ library EnumerableSet { * present. */ function _remove(Set storage set, bytes32 value) private returns (bool) { - // We read and store the value's index to prevent multiple reads from the same storage slot - uint256 valueIndex = set._indexes[value]; + // We cache the value's position to prevent multiple reads from the same storage slot + uint256 position = set._positions[value]; - if (valueIndex != 0) { + if (position != 0) { // Equivalent to contains(set, value) // To delete an element from the _values array in O(1), we swap the element to delete with the last one in // the array, and then remove the last element (sometimes called as 'swap and pop'). // This modifies the order of the array, as noted in {at}. - uint256 toDeleteIndex = valueIndex - 1; + uint256 valueIndex = position - 1; uint256 lastIndex = set._values.length - 1; - if (lastIndex != toDeleteIndex) { + if (valueIndex != lastIndex) { bytes32 lastValue = set._values[lastIndex]; - // Move the last value to the index where the value to delete is - set._values[toDeleteIndex] = lastValue; - // Update the index for the moved value - set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex + // Move the lastValue to the index where the value to delete is + set._values[valueIndex] = lastValue; + // Update the tracked position of the lastValue (that was just moved) + set._positions[lastValue] = position; } // Delete the slot where the moved value was stored set._values.pop(); - // Delete the index for the deleted slot - delete set._indexes[value]; + // Delete the tracked position for the deleted slot + delete set._positions[value]; return true; } else { @@ -118,7 +118,7 @@ library EnumerableSet { * @dev Returns true if the value is in the set. O(1). */ function _contains(Set storage set, bytes32 value) private view returns (bool) { - return set._indexes[value] != 0; + return set._positions[value] != 0; } /** diff --git a/scripts/generate/templates/EnumerableSet.js b/scripts/generate/templates/EnumerableSet.js index 57dd9d8a3..cb9bffb2c 100644 --- a/scripts/generate/templates/EnumerableSet.js +++ b/scripts/generate/templates/EnumerableSet.js @@ -61,9 +61,9 @@ const defaultSet = () => `\ struct Set { // Storage of set values bytes32[] _values; - // Position of the value in the \`values\` array, plus 1 because index 0 - // means a value is not in the set. - mapping(bytes32 value => uint256) _indexes; + // Position is the index of the value in the \`values\` array plus 1. + // Position 0 is used to mean a value is not in the set. + mapping(bytes32 value => uint256) _positions; } /** @@ -77,7 +77,7 @@ function _add(Set storage set, bytes32 value) private returns (bool) { set._values.push(value); // The value is stored at length-1, but we add 1 to all indexes // and use 0 as a sentinel value - set._indexes[value] = set._values.length; + set._positions[value] = set._values.length; return true; } else { return false; @@ -91,32 +91,32 @@ function _add(Set storage set, bytes32 value) private returns (bool) { * present. */ function _remove(Set storage set, bytes32 value) private returns (bool) { - // We read and store the value's index to prevent multiple reads from the same storage slot - uint256 valueIndex = set._indexes[value]; + // We cache the value's position to prevent multiple reads from the same storage slot + uint256 position = set._positions[value]; - if (valueIndex != 0) { + if (position != 0) { // Equivalent to contains(set, value) // To delete an element from the _values array in O(1), we swap the element to delete with the last one in // the array, and then remove the last element (sometimes called as 'swap and pop'). // This modifies the order of the array, as noted in {at}. - uint256 toDeleteIndex = valueIndex - 1; + uint256 valueIndex = position - 1; uint256 lastIndex = set._values.length - 1; - if (lastIndex != toDeleteIndex) { + if (valueIndex != lastIndex) { bytes32 lastValue = set._values[lastIndex]; - // Move the last value to the index where the value to delete is - set._values[toDeleteIndex] = lastValue; - // Update the index for the moved value - set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex + // Move the lastValue to the index where the value to delete is + set._values[valueIndex] = lastValue; + // Update the tracked position of the lastValue (that was just moved) + set._positions[lastValue] = position; } // Delete the slot where the moved value was stored set._values.pop(); - // Delete the index for the deleted slot - delete set._indexes[value]; + // Delete the tracked position for the deleted slot + delete set._positions[value]; return true; } else { @@ -128,7 +128,7 @@ function _remove(Set storage set, bytes32 value) private returns (bool) { * @dev Returns true if the value is in the set. O(1). */ function _contains(Set storage set, bytes32 value) private view returns (bool) { - return set._indexes[value] != 0; + return set._positions[value] != 0; } /**