row-cache: Use ring_position_comparator in some places

The row cache (and memtable) code uses own comparators built on top
of the ring_position_comparator for collections of partitions. These
collections will be switched from the key less-compare to the pair
of token less-compare + key tri-compare.

Prepare for the switch by generalizing the ring_partition_comparator
and by patching all the non-collections usage of less-compare to use
one.

The memtable code doesn't use it outside of collections, but patch it
anyway as a part of preparations.

Signed-off-by: Pavel Emelyanov <xemul@scylladb.com>
This commit is contained in:
Pavel Emelyanov
2020-06-02 20:23:11 +03:00
parent 1e15c06889
commit 7b2754cf5f
4 changed files with 35 additions and 8 deletions

View File

@@ -567,6 +567,12 @@ public:
int ring_position_tri_compare(const schema& s, ring_position_view lh, ring_position_view rh);
template <typename T>
requires std::is_convertible<T, ring_position_view>::value
ring_position_view ring_position_view_to_compare(const T& val) {
return val;
}
// Trichotomic comparator for ring order
struct ring_position_comparator {
const schema& s;
@@ -575,6 +581,21 @@ struct ring_position_comparator {
int operator()(ring_position_view lh, ring_position_view rh) const {
return ring_position_tri_compare(s, lh, rh);
}
template <typename T>
int operator()(const T& lh, ring_position_view rh) const {
return ring_position_tri_compare(s, ring_position_view_to_compare(lh), rh);
}
template <typename T>
int operator()(ring_position_view lh, const T& rh) const {
return ring_position_tri_compare(s, lh, ring_position_view_to_compare(rh));
}
template <typename T1, typename T2>
int operator()(const T1& lh, const T2& rh) const {
return ring_position_tri_compare(s, ring_position_view_to_compare(lh), ring_position_view_to_compare(rh));
}
};
struct ring_position_comparator_for_sstables {

View File

@@ -117,6 +117,7 @@ public:
}
};
friend dht::ring_position_view ring_position_view_to_compare(const memtable_entry& mt) { return mt._key; }
friend std::ostream& operator<<(std::ostream&, const memtable_entry&);
};

View File

@@ -283,13 +283,14 @@ public:
// Can be called on invalid cursor, in which case it brings it back to validity.
// Strong exception guarantees.
bool advance_to(dht::ring_position_view pos) {
auto cmp = cache_entry::compare(_cache.get()._schema);
if (cmp(_end_pos, pos)) { // next() may have moved _start_pos past the _end_pos.
auto lcmp = cache_entry::compare(_cache.get()._schema);
dht::ring_position_comparator cmp(*_cache.get()._schema);
if (cmp(_end_pos, pos) < 0) { // next() may have moved _start_pos past the _end_pos.
_end_pos = pos;
}
_end = _cache.get()._partitions.lower_bound(_end_pos, cmp);
_it = _cache.get()._partitions.lower_bound(pos, cmp);
auto same = !cmp(pos, _it->position());
_end = _cache.get()._partitions.lower_bound(_end_pos, lcmp);
_it = _cache.get()._partitions.lower_bound(pos, lcmp);
auto same = cmp(pos, _it->position()) >= 0;
set_position(*_it);
_last_reclaim_count = _cache.get().get_cache_tracker().allocator().invalidate_counter();
return same;
@@ -754,10 +755,11 @@ row_cache::make_reader(schema_ptr s,
if (!ctx->is_range_query() && !fwd_mr) {
auto mr = _read_section(_tracker.region(), [&] {
return with_linearized_managed_bytes([&] {
cache_entry::compare cmp(_schema);
cache_entry::compare lcmp(_schema);
dht::ring_position_comparator cmp(*_schema);
auto&& pos = ctx->range().start()->value();
auto i = _partitions.lower_bound(pos, cmp);
if (i != _partitions.end() && !cmp(pos, i->position())) {
auto i = _partitions.lower_bound(pos, lcmp);
if (i != _partitions.end() && cmp(pos, i->position()) >= 0) {
cache_entry& e = *i;
upgrade_entry(e);
on_partition_hit();

View File

@@ -137,6 +137,9 @@ public:
}
return _key;
}
friend dht::ring_position_view ring_position_view_to_compare(const cache_entry& ce) noexcept { return ce.position(); }
const partition_entry& partition() const noexcept { return _pe; }
partition_entry& partition() { return _pe; }
const schema_ptr& schema() const noexcept { return _schema; }