|
@@ -49,22 +49,28 @@ library Checkpoints {
|
|
|
|
|
|
/**
|
|
|
* @dev Returns the value at a given block number. If a checkpoint is not available at that block, the closest one
|
|
|
- * before it is returned, or zero otherwise. Similarly to {upperLookup} but optimized for the case when the search
|
|
|
- * key is known to be recent.
|
|
|
+ * before it is returned, or zero otherwise. Similar to {upperLookup} but optimized for the case when the searched
|
|
|
+ * checkpoint is probably "recent", defined as being among the last sqrt(N) checkpoints where N is the number of
|
|
|
+ * checkpoints.
|
|
|
*/
|
|
|
- function getAtRecentBlock(History storage self, uint256 blockNumber) internal view returns (uint256) {
|
|
|
+ function getAtProbablyRecentBlock(History storage self, uint256 blockNumber) internal view returns (uint256) {
|
|
|
require(blockNumber < block.number, "Checkpoints: block not yet mined");
|
|
|
uint32 key = SafeCast.toUint32(blockNumber);
|
|
|
|
|
|
uint256 length = self._checkpoints.length;
|
|
|
- uint256 offset = 1;
|
|
|
|
|
|
- while (offset <= length && _unsafeAccess(self._checkpoints, length - offset)._blockNumber > key) {
|
|
|
- offset <<= 1;
|
|
|
+ uint256 low = 0;
|
|
|
+ uint256 high = length;
|
|
|
+
|
|
|
+ if (length > 5) {
|
|
|
+ uint256 mid = length - Math.sqrt(length);
|
|
|
+ if (key < _unsafeAccess(self._checkpoints, mid)._blockNumber) {
|
|
|
+ high = mid;
|
|
|
+ } else {
|
|
|
+ low = mid + 1;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
- uint256 low = offset < length ? length - offset : 0;
|
|
|
- uint256 high = length - (offset >> 1);
|
|
|
uint256 pos = _upperBinaryLookup(self._checkpoints, key, low, high);
|
|
|
|
|
|
return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value;
|
|
@@ -225,25 +231,6 @@ library Checkpoints {
|
|
|
return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value;
|
|
|
}
|
|
|
|
|
|
- /**
|
|
|
- * @dev Returns the value in the most recent checkpoint with key lower or equal than the search key (similarly to
|
|
|
- * {upperLookup}), optimized for the case when the search key is known to be recent.
|
|
|
- */
|
|
|
- function upperLookupRecent(Trace224 storage self, uint32 key) internal view returns (uint224) {
|
|
|
- uint256 length = self._checkpoints.length;
|
|
|
- uint256 offset = 1;
|
|
|
-
|
|
|
- while (offset <= length && _unsafeAccess(self._checkpoints, length - offset)._key > key) {
|
|
|
- offset <<= 1;
|
|
|
- }
|
|
|
-
|
|
|
- uint256 low = 0 < offset && offset < length ? length - offset : 0;
|
|
|
- uint256 high = length - (offset >> 1);
|
|
|
- uint256 pos = _upperBinaryLookup(self._checkpoints, key, low, high);
|
|
|
-
|
|
|
- return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value;
|
|
|
- }
|
|
|
-
|
|
|
/**
|
|
|
* @dev Pushes a (`key`, `value`) pair into an ordered list of checkpoints, either by inserting a new checkpoint,
|
|
|
* or by updating the last one.
|
|
@@ -380,25 +367,6 @@ library Checkpoints {
|
|
|
return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value;
|
|
|
}
|
|
|
|
|
|
- /**
|
|
|
- * @dev Returns the value in the most recent checkpoint with key lower or equal than the search key (similarly to
|
|
|
- * {upperLookup}), optimized for the case when the search key is known to be recent.
|
|
|
- */
|
|
|
- function upperLookupRecent(Trace160 storage self, uint96 key) internal view returns (uint160) {
|
|
|
- uint256 length = self._checkpoints.length;
|
|
|
- uint256 offset = 1;
|
|
|
-
|
|
|
- while (offset <= length && _unsafeAccess(self._checkpoints, length - offset)._key > key) {
|
|
|
- offset <<= 1;
|
|
|
- }
|
|
|
-
|
|
|
- uint256 low = 0 < offset && offset < length ? length - offset : 0;
|
|
|
- uint256 high = length - (offset >> 1);
|
|
|
- uint256 pos = _upperBinaryLookup(self._checkpoints, key, low, high);
|
|
|
-
|
|
|
- return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value;
|
|
|
- }
|
|
|
-
|
|
|
/**
|
|
|
* @dev Pushes a (`key`, `value`) pair into an ordered list of checkpoints, either by inserting a new checkpoint,
|
|
|
* or by updating the last one.
|