mirror of
https://github.com/scylladb/scylladb.git
synced 2026-06-06 06:53:12 +00:00
Currently `sstable_set::incremental_selector` works in terms of tokens. Sstables can be selected with tokens and internally the token-space is partitioned (in `partitioned_sstable_set`, used for LCS) with tokens as well. This is problematic for severeal reasons. The sub-range sstables cover from the token-space is defined in terms of decorated keys. It is even possible that multiple sstables cover multiple non-overlapping sub-ranges of a single token. The current system is unable to model this and will at best result in selecting unnecessary sstables. The usage of token for providing the next position where the intersecting sstables change [1] causes further problems. Attempting to walk over the token-space by repeatedly calling `select()` with the `next_position` returned from the previous call will quite possibly lead to an infinite loop as a token cannot express inclusiveness/exclusiveness and thus the incremental selector will not be able to make progress when the upper and lower bounds of two neighbouring intervals share the same token with different inclusiveness e.g. [t1, t2](t2, t3]. To solve these problems update incremental_selector to work in terms of ring position. This makes it possible to partition the token-space amoing sstables at decorated key granularity. It also makes it possible for select() to return a next_position that is guaranteed to make progress. partitioned_sstable_set now builds the internal interval map using the decorated key of the sstables, not just the tokens. incremental_selector::select() now uses `dht::ring_position_view` as both the selector and the next_position. ring_position_view can express positions between keys so it can also include information about inclusiveness/exclusiveness of the next interval guaranteeing forward progress. [1] `sstable_set::incremental_selector::selection::next_position`
65 lines
2.4 KiB
C++
65 lines
2.4 KiB
C++
/*
|
|
* Copyright (C) 2016 ScyllaDB
|
|
*/
|
|
|
|
/*
|
|
* This file is part of Scylla.
|
|
*
|
|
* Scylla is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU Affero General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* Scylla is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with Scylla. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
|
|
#pragma once
|
|
|
|
#include "query-request.hh"
|
|
#include <optional>
|
|
|
|
// Wraps ring_position_view so it is compatible with old-style C++: default
|
|
// constructor, stateless comparators, yada yada.
|
|
class compatible_ring_position_view {
|
|
const schema* _schema = nullptr;
|
|
// Optional to supply a default constructor, no more.
|
|
std::optional<dht::ring_position_view> _rpv;
|
|
public:
|
|
constexpr compatible_ring_position_view() = default;
|
|
compatible_ring_position_view(const schema& s, dht::ring_position_view rpv)
|
|
: _schema(&s), _rpv(rpv) {
|
|
}
|
|
const dht::ring_position_view& position() const {
|
|
return *_rpv;
|
|
}
|
|
friend int tri_compare(const compatible_ring_position_view& x, const compatible_ring_position_view& y) {
|
|
return dht::ring_position_tri_compare(*x._schema, *x._rpv, *y._rpv);
|
|
}
|
|
friend bool operator<(const compatible_ring_position_view& x, const compatible_ring_position_view& y) {
|
|
return tri_compare(x, y) < 0;
|
|
}
|
|
friend bool operator<=(const compatible_ring_position_view& x, const compatible_ring_position_view& y) {
|
|
return tri_compare(x, y) <= 0;
|
|
}
|
|
friend bool operator>(const compatible_ring_position_view& x, const compatible_ring_position_view& y) {
|
|
return tri_compare(x, y) > 0;
|
|
}
|
|
friend bool operator>=(const compatible_ring_position_view& x, const compatible_ring_position_view& y) {
|
|
return tri_compare(x, y) >= 0;
|
|
}
|
|
friend bool operator==(const compatible_ring_position_view& x, const compatible_ring_position_view& y) {
|
|
return tri_compare(x, y) == 0;
|
|
}
|
|
friend bool operator!=(const compatible_ring_position_view& x, const compatible_ring_position_view& y) {
|
|
return tri_compare(x, y) != 0;
|
|
}
|
|
};
|
|
|