-
Notifications
You must be signed in to change notification settings - Fork 6
/
SArrays.sol
98 lines (80 loc) · 2.78 KB
/
SArrays.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;
import "@openzeppelin/contracts/utils/math/Math.sol";
/**
* @dev Collection of functions related to array types.
*/
library SArrays {
/**
* @dev Searches a sorted `array` and returns the first index that contains
* a value greater or equal to `element`. If no such index exists (i.e. all
* values in the array are strictly less than `element`), the array length is
* returned. Time complexity O(log n).
*
* `array` is expected to be sorted in ascending order, and to contain no
* repeated elements.
*/
function findUpperBound(uint256[] storage array, uint256 element) internal view returns (uint256) {
if (array.length == 0) {
return 0;
}
uint256 low = 0;
uint256 high = array.length;
while (low < high) {
uint256 mid = Math.average(low, high);
// Note that mid will always be strictly less than high (i.e. it will be a valid array index)
// because Math.average rounds down (it does integer division with truncation).
if (array[mid] > element) {
high = mid;
} else {
low = mid + 1;
}
}
// At this point `low` is the exclusive upper bound. We will return the inclusive upper bound.
if (low > 0 && array[low - 1] == element) {
return low - 1;
} else {
return low;
}
}
function findIndex(uint256[] storage array, uint256 element
) internal view returns (uint256) {
if (array.length == 0) return 0;
// Shortcut for the actual value
if (element >= array[array.length-1])
return (array.length-1);
if (element < array[0]) return 0;
// Binary search of the value in the array
uint min = 0;
uint max = array.length-1;
while (max > min) {
uint mid = (max + min + 1)/ 2;
if (array[mid] <= element) {
min = mid;
} else {
max = mid-1;
}
}
return min;
}
function findValue(uint256[] storage array, uint256 element
) internal view returns (uint256) {
if (array.length == 0) return 0;
// Shortcut for the actual value
if (element >= array[array.length-1])
return (array[array.length-1]);
if (element < array[0]) return 0;
// Binary search of the value in the array
uint min = 0;
uint max = array.length-1;
while (max > min) {
uint mid = (max + min + 1)/ 2;
if (array[mid] <= element) {
min = mid;
} else {
max = mid-1;
}
}
return array[min];
}
}