@@ -24,23 +24,16 @@ BTree::BTree(
24
24
25
25
using CompareResult = std::pair<int , BytesOrByteView>;
26
26
27
- static CompareResult compare_key (
27
+ static std::optional< CompareResult> compare_key (
28
28
ByteView key,
29
29
BTree::DataIndex key_index,
30
30
const BTree::KeyValueIndex& index) {
31
31
auto data_key = index.lookup_key (key_index);
32
- ensure (data_key.has_value (), [&] { return " out-of-bounds key=" + to_hex (key) + " data_index=" + std::to_string (key_index); });
32
+ if (!data_key) {
33
+ return std::nullopt;
34
+ }
33
35
int cmp = ByteView{*data_key}.compare (key);
34
- return {cmp, std::move (*data_key)};
35
- }
36
-
37
- static BTree::KeyValueIndex::LookupResult lookup_key_value (
38
- ByteView key,
39
- BTree::DataIndex key_index,
40
- const BTree::KeyValueIndex& index) {
41
- auto result = index.lookup_key_value (key_index, key);
42
- ensure (result.has_value (), [&] { return " out-of-bounds key=" + to_hex (key) + " data_index=" + std::to_string (key_index); });
43
- return std::move (*result);
36
+ return CompareResult{cmp, std::move (*data_key)};
44
37
}
45
38
46
39
BTree::SeekResult BTree::seek (ByteView seek_key, const KeyValueIndex& index) {
@@ -55,8 +48,12 @@ BTree::SeekResult BTree::seek(ByteView seek_key, const KeyValueIndex& index) {
55
48
auto [_, left_index, right_index] = binary_search_in_cache (seek_key); // left_index == right_index when key is found
56
49
uint64_t median = 0 ;
57
50
while (left_index < right_index) {
58
- if (right_index - left_index <= kDefaultBtreeStartSkip ) { // found small range, faster to scan now
59
- const auto [cmp, key] = compare_key (seek_key, left_index, index);
51
+ if (right_index - left_index <= kDefaultBtreeStartSkip ) { // found a small range, faster to scan now
52
+ const auto cmp_result = compare_key (seek_key, left_index, index);
53
+ if (!cmp_result) {
54
+ return {/* found=*/ false , {}, {}, 0 };
55
+ }
56
+ const auto [cmp, key] = *cmp_result;
60
57
if (cmp == 0 ) {
61
58
right_index = left_index;
62
59
break ;
@@ -71,7 +68,11 @@ BTree::SeekResult BTree::seek(ByteView seek_key, const KeyValueIndex& index) {
71
68
break ;
72
69
}
73
70
median = (left_index + right_index) >> 1 ;
74
- const auto [cmp, key] = compare_key (seek_key, median, index);
71
+ const auto cmp_result = compare_key (seek_key, median, index);
72
+ if (!cmp_result) {
73
+ return {/* found=*/ false , {}, {}, 0 };
74
+ }
75
+ const auto [cmp, key] = *cmp_result;
75
76
if (cmp == 0 ) {
76
77
left_index = right_index = median;
77
78
break ;
@@ -107,7 +108,7 @@ std::optional<BytesOrByteView> BTree::get(ByteView key, const KeyValueIndex& ind
107
108
}
108
109
auto [_, left_index, right_index] = binary_search_in_cache (key); // left_index == right_index when key is found
109
110
while (left_index < right_index) {
110
- if (right_index - left_index <= kDefaultBtreeStartSkip ) { // found small range, faster to scan now
111
+ if (right_index - left_index <= kDefaultBtreeStartSkip ) { // found a small range, faster to scan now
111
112
auto value = index.advance_key_value (left_index, key, right_index - left_index);
112
113
if (!value) {
113
114
left_index = right_index;
@@ -116,7 +117,11 @@ std::optional<BytesOrByteView> BTree::get(ByteView key, const KeyValueIndex& ind
116
117
return value;
117
118
}
118
119
const uint64_t median = (left_index + right_index) >> 1 ;
119
- auto [cmp, optional_v] = lookup_key_value (key, median, index);
120
+ const auto lookup_result = index.lookup_key_value (median, key);
121
+ if (!lookup_result) {
122
+ return std::nullopt;
123
+ }
124
+ const auto [cmp, optional_v] = *lookup_result;
120
125
if (cmp == 0 ) {
121
126
SILKWORM_ASSERT (optional_v);
122
127
return optional_v;
@@ -127,7 +132,11 @@ std::optional<BytesOrByteView> BTree::get(ByteView key, const KeyValueIndex& ind
127
132
left_index = median + 1 ;
128
133
}
129
134
}
130
- auto [cmp, optional_v] = lookup_key_value (key, left_index, index);
135
+ const auto lookup_result = index.lookup_key_value (left_index, key);
136
+ if (!lookup_result) {
137
+ return std::nullopt;
138
+ }
139
+ const auto [cmp, optional_v] = *lookup_result;
131
140
if (cmp != 0 ) {
132
141
return std::nullopt;
133
142
}
@@ -157,7 +166,9 @@ void BTree::warmup(const KeyValueIndex& index) {
157
166
const size_t step = num_nodes_ < fanout_ ? 1 : fanout_; // cache all keys if less than M
158
167
for (size_t i{step}; i < num_nodes_; i += step) {
159
168
const size_t data_index = i - 1 ;
160
- auto [_, key] = compare_key ({}, data_index, index);
169
+ auto cmp_result = compare_key ({}, data_index, index);
170
+ if (!cmp_result) continue ;
171
+ auto [_, key] = *cmp_result;
161
172
cache_.emplace_back (Node{data_index, Bytes{key}});
162
173
cached_bytes += sizeof (Node) + ByteView{key}.size ();
163
174
}
@@ -185,7 +196,11 @@ BTree::Nodes BTree::decode_nodes(std::span<uint8_t> encoded_nodes) {
185
196
186
197
void BTree::check_against_data_keys (const KeyValueIndex& index) {
187
198
for (const auto & node : cache_) {
188
- const auto [cmp, key] = compare_key (node.key , node.key_index , index);
199
+ const auto cmp_result = compare_key (node.key , node.key_index , index);
200
+ ensure (cmp_result.has_value (), [&] {
201
+ return " out-of-bounds key=" + to_hex (node.key ) + " data_index=" + std::to_string (node.key_index );
202
+ });
203
+ const auto [cmp, key] = *cmp_result;
189
204
ensure (cmp == 0 , [&]() {
190
205
return " key mismatch node.key=" + to_hex (node.key ) +
191
206
" key=" + to_hex (key) +
0 commit comments