partition_snapshot_reader: Avoid quadratic behavior with lots of range tombstones
next_range_tombstone() was populating _rt_stream on each invocation from the current iterator ranges in _range_tombstones. If there is a lot of range tombstones, all would be put into _rt_stream. One problem is that this can cause a reactor stall. Fix by more incremental approach where we populate _rt_stream with minimal amount on each invocation of next_range_tombstone(). Another problem is that this can get quadratic. The iterators in _range_tombstones are advanced, but if lsa invalidates them across calls they can revert back to the front since they go back to _last_rt, which is the last consumed range tombstone, and if the buffer fills up, not all tombstones from _rt_stream could be consumed. The new code doesn't have this problem because everything which is produced out of the iterators in _range_tombstones is produced only once. What we put into _rt_stream is consumed first before we try to feed the _rt_stream with more data.
This commit is contained in:
@@ -245,11 +245,16 @@ class partition_snapshot_flat_reader : public flat_mutation_reader::impl, public
|
||||
const std::optional<position_in_partition>& last_row,
|
||||
const std::optional<position_in_partition>& last_rts,
|
||||
position_in_partition_view pos) {
|
||||
if (!_rt_stream.empty()) {
|
||||
return _rt_stream.get_next(std::move(pos));
|
||||
}
|
||||
return in_alloc_section([&] () -> mutation_fragment_opt {
|
||||
maybe_refresh_state(ck_range, last_row, last_rts);
|
||||
|
||||
position_in_partition::less_compare rt_less(_schema);
|
||||
while (has_more_range_tombstones() && !rt_less(pos, peek_range_tombstone().position())) {
|
||||
while (has_more_range_tombstones()
|
||||
&& !rt_less(pos, peek_range_tombstone().position())
|
||||
&& (_rt_stream.empty() || !rt_less(_rt_stream.peek_next().position(), peek_range_tombstone().position()))) {
|
||||
range_tombstone rt = pop_range_tombstone();
|
||||
if (rt.trim(_schema,
|
||||
position_in_partition_view::for_range_start(ck_range),
|
||||
|
||||
Reference in New Issue
Block a user