storage_proxy: Fix range splitting when split point is exlcluded by lower bound

If we had a range (x; ...] then x is excluded, but token iterator was
initialized with x. The splitting loop would exit prematurely because
it would detect that the token is outside the range.

The fix is to teach ring_range() to recognize this and always give
tokens which are not smaller than the range's lower bound.
This commit is contained in:
Tomasz Grabiec
2015-07-22 10:12:58 +02:00
parent c219c3676b
commit 6882e6ca50
3 changed files with 26 additions and 1 deletions

View File

@@ -198,6 +198,27 @@ void token_metadata::add_bootstrap_token(token t, inet_address endpoint) {
add_bootstrap_tokens(tokens, endpoint);
}
boost::iterator_range<token_metadata::tokens_iterator>
token_metadata::ring_range(
const std::experimental::optional<query::partition_range::bound>& start,
bool include_min)
{
auto r = ring_range(start ? start->value().token() : dht::minimum_token(), include_min);
if (!r.empty()) {
// We should skip the first token if it's excluded by the range.
if (start
&& !start->is_inclusive()
&& !start->value().has_key()
&& start->value().token() == *r.begin())
{
r.pop_front();
}
}
return r;
}
void token_metadata::add_bootstrap_tokens(std::unordered_set<token> tokens, inet_address endpoint) {
for (auto t : tokens) {
auto old_endpoint = _bootstrap_tokens.find(t);

View File

@@ -29,6 +29,7 @@
#include "utils/UUID.hh"
#include <experimental/optional>
#include <boost/range/iterator_range.hpp>
#include "query-request.hh"
// forward declaration since database.hh includes this file
class keyspace;
@@ -228,6 +229,9 @@ public:
return boost::make_iterator_range(begin, end);
}
boost::iterator_range<tokens_iterator> ring_range(
const std::experimental::optional<query::partition_range::bound>& start, bool include_min = false);
topology& get_topology() {
return _topology;
}

View File

@@ -2457,7 +2457,7 @@ storage_proxy::get_restricted_ranges(keyspace& ks, const schema& s, query::parti
std::vector<query::partition_range> ranges;
// divide the queryRange into pieces delimited by the ring and minimum tokens
auto ring_iter = tm.ring_range(start_token(range), true);
auto ring_iter = tm.ring_range(range.start(), true);
query::partition_range remainder = std::move(range);
for (const dht::token& upper_bound_token : ring_iter)
{