Files
scylladb/test/lib/index_reader_assertions.hh
Tomasz Grabiec 5ed559c8c6 sstables: index_reader: Do not store cluster index cursor inside partition indexes
Currently, the partition index page parser will create and store
promoted index cursors for each entry. The assumption is that
partition index pages are not shared by readers so each promoted index
cursor will be used by a single index_reader (the top-level cursor).

In order to be able to share partition index entries we must make the
entries immutable and thus move the cursor outside. The promoted index
cursor is now created and owned by each index_reader. There is at most
one such active cursor per index_reader bound (lower/upper).
2021-02-04 15:23:55 +01:00

84 lines
3.0 KiB
C++

/*
* Copyright (C) 2017 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 <boost/test/unit_test.hpp>
#include "dht/i_partitioner.hh"
#include "schema.hh"
#include "sstables/index_reader.hh"
class index_reader_assertions {
std::unique_ptr<sstables::index_reader> _r;
public:
index_reader_assertions(std::unique_ptr<sstables::index_reader> r)
: _r(std::move(r))
{ }
index_reader_assertions& has_monotonic_positions(const schema& s) {
auto pos_cmp = sstables::promoted_index_block_compare(s);
auto rp_cmp = dht::ring_position_comparator(s);
auto prev = dht::ring_position::min();
_r->read_partition_data().get();
while (!_r->eof()) {
auto& e = _r->current_partition_entry();
auto k = e.get_decorated_key();
auto token = dht::token(k.token());
auto rp = dht::ring_position(token, k.key().to_partition_key(s));
if (!rp_cmp(prev, rp)) {
BOOST_FAIL(format("Partitions have invalid order: {} >= {}", prev, rp));
}
prev = rp;
std::unique_ptr<sstables::clustered_index_cursor> cur = e.get_promoted_index()->make_cursor(
_r->sstable(), tests::make_permit(), nullptr, {});
std::optional<sstables::promoted_index_block_position> prev_end;
while (auto ei_opt = cur->next_entry().get0()) {
sstables::clustered_index_cursor::entry_info& ei = *ei_opt;
if (prev_end && pos_cmp(ei.start, sstables::to_view(*prev_end))) {
BOOST_FAIL(format("Index blocks are not monotonic: {} > {}", *prev_end, ei.start));
}
prev_end = sstables::materialize(ei.end);
}
_r->advance_to_next_partition().get();
}
return *this;
}
index_reader_assertions& is_empty(const schema& s) {
_r->read_partition_data().get();
while (!_r->eof()) {
sstables::index_entry& ie = _r->current_partition_entry();
BOOST_REQUIRE(!ie.get_promoted_index() || ie.get_promoted_index()->get_promoted_index_size() == 0);
_r->advance_to_next_partition().get();
}
return *this;
}
};
inline
index_reader_assertions assert_that(std::unique_ptr<sstables::index_reader> r) {
return { std::move(r) };
}