-
Notifications
You must be signed in to change notification settings - Fork 592
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
cloud_storage: use remote index in cloud timequery #13011
Changes from all commits
c1d0314
da8533b
b78d711
6d507cd
de5aa53
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -115,73 +115,114 @@ std:: | |
|
||
std::optional<offset_index::find_result> | ||
offset_index::find_rp_offset(model::offset upper_bound) { | ||
size_t ix = 0; | ||
find_result res{}; | ||
|
||
auto search_result = maybe_find_offset(upper_bound, _rp_index, _rp_offsets); | ||
|
||
if (std::holds_alternative<std::monostate>(search_result)) { | ||
return std::nullopt; | ||
} else if (std::holds_alternative<find_result>(search_result)) { | ||
return std::get<find_result>(search_result); | ||
} | ||
auto maybe_ix = std::get<index_value>(search_result); | ||
|
||
// Invariant: maybe_ix here can't be nullopt | ||
ix = maybe_ix.ix; | ||
res.rp_offset = model::offset(maybe_ix.value); | ||
|
||
decoder_t kaf_dec( | ||
_kaf_index.get_initial_value(), | ||
_kaf_index.get_row_count(), | ||
_kaf_index.copy()); | ||
auto kaf_offset = _fetch_ix(std::move(kaf_dec), ix); | ||
vassert(kaf_offset.has_value(), "Inconsistent index state"); | ||
res.kaf_offset = kafka::offset(*kaf_offset); | ||
foffset_decoder_t file_dec( | ||
_file_index.get_initial_value(), | ||
_file_index.get_row_count(), | ||
_file_index.copy(), | ||
delta_delta_t(_min_file_pos_step)); | ||
auto file_pos = _fetch_ix(std::move(file_dec), ix); | ||
res.file_pos = *file_pos; | ||
return res; | ||
return ss::visit( | ||
search_result, | ||
[](std::monostate) -> std::optional<find_result> { return std::nullopt; }, | ||
[](find_result result) -> std::optional<find_result> { return result; }, | ||
[this](index_value index_result) -> std::optional<find_result> { | ||
find_result res{}; | ||
|
||
size_t ix = index_result.ix; | ||
res.rp_offset = model::offset(index_result.value); | ||
|
||
decoder_t kaf_dec( | ||
_kaf_index.get_initial_value(), | ||
_kaf_index.get_row_count(), | ||
_kaf_index.copy()); | ||
auto kaf_offset = _fetch_ix(std::move(kaf_dec), ix); | ||
vassert(kaf_offset.has_value(), "Inconsistent index state"); | ||
res.kaf_offset = kafka::offset(*kaf_offset); | ||
foffset_decoder_t file_dec( | ||
_file_index.get_initial_value(), | ||
_file_index.get_row_count(), | ||
_file_index.copy(), | ||
delta_delta_t(_min_file_pos_step)); | ||
auto file_pos = _fetch_ix(std::move(file_dec), ix); | ||
res.file_pos = *file_pos; | ||
return res; | ||
}); | ||
} | ||
|
||
std::optional<offset_index::find_result> | ||
offset_index::find_kaf_offset(kafka::offset upper_bound) { | ||
size_t ix = 0; | ||
find_result res{}; | ||
|
||
auto search_result = maybe_find_offset( | ||
upper_bound, _kaf_index, _kaf_offsets); | ||
return ss::visit( | ||
search_result, | ||
[](std::monostate) -> std::optional<find_result> { return std::nullopt; }, | ||
[](find_result result) -> std::optional<find_result> { return result; }, | ||
[this](index_value index_result) -> std::optional<find_result> { | ||
find_result res{}; | ||
|
||
size_t ix = index_result.ix; | ||
res.kaf_offset = kafka::offset(index_result.value); | ||
|
||
decoder_t rp_dec( | ||
_rp_index.get_initial_value(), | ||
_rp_index.get_row_count(), | ||
_rp_index.copy()); | ||
auto rp_offset = _fetch_ix(std::move(rp_dec), ix); | ||
vassert(rp_offset.has_value(), "Inconsistent index state"); | ||
res.rp_offset = model::offset(*rp_offset); | ||
foffset_decoder_t file_dec( | ||
_file_index.get_initial_value(), | ||
_file_index.get_row_count(), | ||
_file_index.copy(), | ||
delta_delta_t(_min_file_pos_step)); | ||
auto file_pos = _fetch_ix(std::move(file_dec), ix); | ||
res.file_pos = *file_pos; | ||
return res; | ||
}); | ||
} | ||
|
||
if (std::holds_alternative<std::monostate>(search_result)) { | ||
std::optional<offset_index::find_result> | ||
offset_index::find_timestamp(model::timestamp upper_bound) { | ||
if (_initial_time == model::timestamp::missing()) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. it's a bummer that -1 is used to indicate missing timestamp. That -1 carries so much additional baggage in Kafka for example by indicating something specific in time queries. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah, it's not ideal. Not much we can do about it now though. The -1 is already encoded in a released Serde version. |
||
// Bail out early if this is a version 1 index | ||
// that does not index timestamps. | ||
return std::nullopt; | ||
} else if (std::holds_alternative<find_result>(search_result)) { | ||
return std::get<find_result>(search_result); | ||
} | ||
auto maybe_ix = std::get<index_value>(search_result); | ||
|
||
// Invariant: maybe_ix here can't be nullopt | ||
ix = maybe_ix.ix; | ||
res.kaf_offset = kafka::offset(maybe_ix.value); | ||
|
||
decoder_t rp_dec( | ||
_rp_index.get_initial_value(), | ||
_rp_index.get_row_count(), | ||
_rp_index.copy()); | ||
auto rp_offset = _fetch_ix(std::move(rp_dec), ix); | ||
vassert(rp_offset.has_value(), "Inconsistent index state"); | ||
res.rp_offset = model::offset(*rp_offset); | ||
foffset_decoder_t file_dec( | ||
_file_index.get_initial_value(), | ||
_file_index.get_row_count(), | ||
_file_index.copy(), | ||
delta_delta_t(_min_file_pos_step)); | ||
auto file_pos = _fetch_ix(std::move(file_dec), ix); | ||
res.file_pos = *file_pos; | ||
return res; | ||
auto search_result = maybe_find_offset( | ||
upper_bound.value(), _time_index, _time_offsets); | ||
|
||
return ss::visit( | ||
search_result, | ||
[](std::monostate) -> std::optional<find_result> { return std::nullopt; }, | ||
[](find_result result) -> std::optional<find_result> { return result; }, | ||
[this](index_value index_result) -> std::optional<find_result> { | ||
size_t ix = index_result.ix; | ||
|
||
// Decode all offset indices to build up the result. | ||
decoder_t rp_dec( | ||
_rp_index.get_initial_value(), | ||
_rp_index.get_row_count(), | ||
_rp_index.copy()); | ||
auto rp_offset = _fetch_ix(std::move(rp_dec), ix); | ||
vassert(rp_offset.has_value(), "Inconsistent index state"); | ||
|
||
decoder_t kaf_dec( | ||
_kaf_index.get_initial_value(), | ||
_kaf_index.get_row_count(), | ||
_kaf_index.copy()); | ||
auto kaf_offset = _fetch_ix(std::move(kaf_dec), ix); | ||
vassert(kaf_offset.has_value(), "Inconsistent index state"); | ||
|
||
foffset_decoder_t file_dec( | ||
_file_index.get_initial_value(), | ||
_file_index.get_row_count(), | ||
_file_index.copy(), | ||
delta_delta_t(_min_file_pos_step)); | ||
auto file_pos = _fetch_ix(std::move(file_dec), ix); | ||
vassert(file_pos.has_value(), "Inconsistent index state"); | ||
|
||
return offset_index::find_result{ | ||
.rp_offset = model::offset(*rp_offset), | ||
.kaf_offset = kafka::offset(*kaf_offset), | ||
.file_pos = *file_pos}; | ||
}); | ||
} | ||
|
||
offset_index::coarse_index_t offset_index::build_coarse_index( | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is it odd that
first_timestamp
wasn't used in this conditional before?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
first_timestamp
indicates that this is a time-query. By this point, we have already resolved to the correct segment for the time query. Since we didn't previously used the index, it makes senes thatfirst_timestamp
wasn't used (we'd just start from the beginning of the segment).