Memtables are a replica-side entity, and so are moved to the replica module and namespace. Memtables are also used outside the replica, in two places: - in some virtual tables; this is also in some way inside the replica, (virtual readers are installed at the replica level, not the cooordinator), so I don't consider it a layering violation - in many sstable unit tests, as a convenient way to create sstables with known input. This is a layering violation. We could make memtables their own module, but I think this is wrong. Memtables are deeply tied into replica memory management, and trying to make them a low-level primitive (at a lower level than sstables) will be difficult. Not least because memtables use sstables. Instead, we should have a memtable-like thing that doesn't support merging and doesn't have all other funky memtable stuff, and instead replace the uses of memtables in sstable tests with some kind of make_flat_mutation_reader_from_unsorted_mutations() that does the sorting that is the reason for the use of memtables in tests (and live with the layering violation meanwhile). Test: unit (dev) Closes #10120
77 lines
3.0 KiB
C++
77 lines
3.0 KiB
C++
/*
|
|
* Copyright (C) 2015-present ScyllaDB
|
|
*/
|
|
|
|
/*
|
|
* SPDX-License-Identifier: AGPL-3.0-or-later
|
|
*/
|
|
|
|
|
|
#include <boost/test/unit_test.hpp>
|
|
#include <seastar/testing/test_case.hh>
|
|
#include <seastar/testing/thread_test_case.hh>
|
|
#include <seastar/core/thread.hh>
|
|
#include "sstables/sstables.hh"
|
|
#include "timestamp.hh"
|
|
#include "schema_builder.hh"
|
|
#include "mutation_reader.hh"
|
|
#include "test/lib/mutation_source_test.hh"
|
|
#include "test/lib/flat_mutation_reader_assertions.hh"
|
|
#include "test/lib/sstable_utils.hh"
|
|
|
|
using namespace sstables;
|
|
using namespace std::chrono_literals;
|
|
|
|
SEASTAR_TEST_CASE(test_schema_changes) {
|
|
return sstables::test_env::do_with_async([] (sstables::test_env& env) {
|
|
auto dir = tmpdir();
|
|
int gen = 1;
|
|
|
|
std::map<std::tuple<sstables::sstable::version_types, schema_ptr>, std::tuple<shared_sstable, int>> cache;
|
|
for_each_schema_change([&] (schema_ptr base, const std::vector<mutation>& base_mutations,
|
|
schema_ptr changed, const std::vector<mutation>& changed_mutations) {
|
|
for (auto version : writable_sstable_versions) {
|
|
auto it = cache.find(std::tuple { version, base });
|
|
|
|
shared_sstable created_with_base_schema;
|
|
shared_sstable created_with_changed_schema;
|
|
if (it == cache.end()) {
|
|
auto mt = make_lw_shared<replica::memtable>(base);
|
|
for (auto& m : base_mutations) {
|
|
mt->apply(m);
|
|
}
|
|
|
|
created_with_base_schema = make_sstable_easy(env, dir.path(), mt, env.manager().configure_writer(), gen, version, base_mutations.size());
|
|
|
|
created_with_changed_schema = env.make_sstable(changed, dir.path().string(), gen, version, sstables::sstable::format_types::big);
|
|
created_with_changed_schema->load().get();
|
|
|
|
cache.emplace(std::tuple { version, base }, std::tuple { created_with_base_schema, gen });
|
|
gen++;
|
|
} else {
|
|
created_with_base_schema = std::get<shared_sstable>(it->second);
|
|
|
|
created_with_changed_schema = env.make_sstable(changed, dir.path().string(), std::get<int>(it->second), version, sstables::sstable::format_types::big);
|
|
created_with_changed_schema->load().get();
|
|
}
|
|
|
|
const auto pr = dht::partition_range::make_open_ended_both_sides();
|
|
|
|
auto mr = assert_that(created_with_base_schema->as_mutation_source()
|
|
.make_reader(changed, env.make_reader_permit(), pr, changed->full_slice()));
|
|
for (auto& m : changed_mutations) {
|
|
mr.produces(m);
|
|
}
|
|
mr.produces_end_of_stream();
|
|
|
|
mr = assert_that(created_with_changed_schema->as_mutation_source()
|
|
.make_reader(changed, env.make_reader_permit(), pr, changed->full_slice()));
|
|
for (auto& m : changed_mutations) {
|
|
mr.produces(m);
|
|
}
|
|
mr.produces_end_of_stream();
|
|
}
|
|
});
|
|
});
|
|
}
|