clustering_ranges_walker: Generalize to work on position ranges

It will include the static row by default. This will allow simplifying
users, which work with position ranges already.
This commit is contained in:
Tomasz Grabiec
2017-04-07 10:23:26 +02:00
parent c85fe3183c
commit 652d04e78a

View File

@@ -27,19 +27,38 @@
#include "query-request.hh"
#include "streamed_mutation.hh"
// Utility for in-order checking of overlap with clustering ranges.
// Utility for in-order checking of overlap with position ranges.
// Always includes the static row initially.
class clustering_ranges_walker {
const schema& _schema;
const query::clustering_row_ranges& _ranges;
query::clustering_row_ranges::const_iterator _current;
query::clustering_row_ranges::const_iterator _end;
bool _in_current = false;
bool _in_current; // next position is known to be >= _current_start
position_in_partition_view _current_start;
position_in_partition_view _current_end;
private:
bool advance_to_next_range() {
_in_current = false;
if (!_current_start.is_static_row()) {
++_current;
}
if (_current == _end) {
return false;
}
_current_start = position_in_partition_view::for_range_start(*_current);
_current_end = position_in_partition_view::for_range_end(*_current);
return true;
}
public:
clustering_ranges_walker(const schema& s, const query::clustering_row_ranges& ranges)
: _schema(s)
, _ranges(ranges)
, _current(ranges.begin())
, _end(ranges.end())
, _in_current(true)
, _current_start(position_in_partition_view::for_static_row())
, _current_end(position_in_partition_view::before_all_clustered_rows())
{ }
clustering_ranges_walker(clustering_ranges_walker&& o) noexcept
: _schema(o._schema)
@@ -47,6 +66,8 @@ public:
, _current(o._current)
, _end(o._end)
, _in_current(o._in_current)
, _current_start(o._current_start)
, _current_end(o._current_end)
{ }
clustering_ranges_walker& operator=(clustering_ranges_walker&& o) {
if (this != &o) {
@@ -62,29 +83,22 @@ public:
bool advance_to(position_in_partition_view pos) {
position_in_partition::less_compare less(_schema);
while (_current != _end) {
if (!_in_current && _current->start()) {
auto range_start = position_in_partition_view::for_range_start(*_current);
if (less(pos, range_start)) {
return false;
}
if (_current == _end) {
return false;
}
do {
if (!_in_current && less(pos, _current_start)) {
break;
}
// All subsequent clustering keys are larger than the start of this
// range so there is no need to check that again.
_in_current = true;
if (!_current->end()) {
if (less(pos, _current_end)) {
return true;
}
auto range_end = position_in_partition_view::for_range_end(*_current);
if (less(pos, range_end)) {
return true;
}
++_current;
_in_current = false;
}
} while (advance_to_next_range());
return false;
}
@@ -97,20 +111,18 @@ public:
bool advance_to(position_in_partition_view start, position_in_partition_view end) {
position_in_partition::less_compare less(_schema);
while (_current != _end) {
position_in_partition_view range_start(position_in_partition_view::range_tag_t(), bound_view::from_range_start(*_current));
if (less(end, range_start)) {
return false;
}
if (_current == _end) {
return false;
}
position_in_partition_view range_end(position_in_partition_view::range_tag_t(), bound_view::from_range_end(*_current));
if (less(start, range_end)) {
do {
if (less(end, _current_start)) {
break;
}
if (less(start, _current_end)) {
return true;
}
++_current;
_in_current = false;
}
} while (advance_to_next_range());
return false;
}
@@ -123,6 +135,8 @@ public:
// Resets the state of the walker so that advance_to() can be now called for new sequence of positions.
void reset() {
_current = _ranges.begin();
_in_current = false;
_current_start = position_in_partition_view::for_static_row();
_current_end = position_in_partition_view::before_all_clustered_rows();
_in_current = true;
}
};