schema: introduce make_reversed()
`make_revered()` creates a schema identical to the schema instance it is called on, with clustering order reversed. To distinguish the reverse schema from the original one, the node-id part of its version UUID is bit-flipped. This ensures that reversing a schema twice will result in the identical schema to the original one (although a different C++ object). This reversed schema will be used in reversed reads, so intermediate layers can be ignorant of the fact that the read happens in reverse.
This commit is contained in:
16
schema.cc
16
schema.cc
@@ -439,6 +439,18 @@ schema::schema(const schema& o)
|
||||
{
|
||||
}
|
||||
|
||||
schema::schema(reversed_tag, const schema& o)
|
||||
: schema(o, [] (schema& s) {
|
||||
s._raw._version = utils::UUID_gen::negate(s._raw._version);
|
||||
for (auto& col : s._raw._columns) {
|
||||
if (col.kind == column_kind::clustering_key) {
|
||||
col.type = reversed(col.type);
|
||||
}
|
||||
}
|
||||
})
|
||||
{
|
||||
}
|
||||
|
||||
lw_shared_ptr<const schema> make_shared_schema(std::optional<utils::UUID> id, std::string_view ks_name,
|
||||
std::string_view cf_name, std::vector<schema::column> partition_key, std::vector<schema::column> clustering_key,
|
||||
std::vector<schema::column> regular_columns, std::vector<schema::column> static_columns,
|
||||
@@ -1579,6 +1591,10 @@ bool schema::equal_columns(const schema& other) const {
|
||||
return boost::equal(all_columns(), other.all_columns());
|
||||
}
|
||||
|
||||
schema_ptr schema::make_reversed() const {
|
||||
return make_lw_shared<schema>(schema::reversed_tag{}, *this);
|
||||
}
|
||||
|
||||
raw_view_info::raw_view_info(utils::UUID base_id, sstring base_name, bool include_all_columns, sstring where_clause)
|
||||
: _base_id(std::move(base_id))
|
||||
, _base_name(std::move(base_name))
|
||||
|
||||
21
schema.hh
21
schema.hh
@@ -584,6 +584,10 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
class schema;
|
||||
|
||||
using schema_ptr = lw_shared_ptr<const schema>;
|
||||
|
||||
/*
|
||||
* Effectively immutable.
|
||||
* Not safe to access across cores because of shared_ptr's.
|
||||
@@ -695,12 +699,16 @@ public:
|
||||
data_type type;
|
||||
};
|
||||
private:
|
||||
struct reversed_tag { };
|
||||
|
||||
lw_shared_ptr<cql3::column_specification> make_column_specification(const column_definition& def);
|
||||
void rebuild();
|
||||
schema(const raw_schema&, std::optional<raw_view_info>);
|
||||
schema(const schema&, const std::function<void(schema&)>&);
|
||||
public:
|
||||
schema(const schema&);
|
||||
// See \ref make_reversed().
|
||||
schema(reversed_tag, const schema&);
|
||||
~schema();
|
||||
table_schema_version version() const {
|
||||
return _raw._version;
|
||||
@@ -967,6 +975,17 @@ public:
|
||||
const v3_columns& v3() const {
|
||||
return _v3_columns;
|
||||
}
|
||||
|
||||
// Make a copy of the schema with reversed clustering order.
|
||||
//
|
||||
// The reversing is revertible, so that:
|
||||
//
|
||||
// s->make_reversed()->make_reversed()->version() == s->version()
|
||||
//
|
||||
// But note that: `s != s->make_reversed()->make_reversed()` (they are two
|
||||
// different C++ objects).
|
||||
// The schema's version is also reversed using UUID_gen::negate().
|
||||
schema_ptr make_reversed() const;
|
||||
};
|
||||
|
||||
lw_shared_ptr<const schema> make_shared_schema(std::optional<utils::UUID> id, std::string_view ks_name, std::string_view cf_name,
|
||||
@@ -975,8 +994,6 @@ lw_shared_ptr<const schema> make_shared_schema(std::optional<utils::UUID> id, st
|
||||
|
||||
bool operator==(const schema&, const schema&);
|
||||
|
||||
using schema_ptr = lw_shared_ptr<const schema>;
|
||||
|
||||
/**
|
||||
* Wrapper for schema_ptr used by functions that expect an engaged view_info field.
|
||||
*/
|
||||
|
||||
@@ -42,6 +42,7 @@
|
||||
#include "test/lib/log.hh"
|
||||
#include "serializer_impl.hh"
|
||||
#include "cdc/cdc_extension.hh"
|
||||
#include "utils/UUID_gen.hh"
|
||||
|
||||
SEASTAR_TEST_CASE(test_new_schema_with_no_structural_change_is_propagated) {
|
||||
return do_with_cql_env([](cql_test_env& e) {
|
||||
@@ -807,3 +808,26 @@ SEASTAR_TEST_CASE(test_schema_tables_use_null_sharder) {
|
||||
}).get();
|
||||
}, raft_cql_test_config());
|
||||
}
|
||||
|
||||
SEASTAR_TEST_CASE(test_schema_make_reversed) {
|
||||
auto schema = schema_builder("tests", get_name())
|
||||
.with_column("pk", bytes_type, column_kind::partition_key)
|
||||
.with_column("ck", bytes_type, column_kind::clustering_key)
|
||||
.with_column("v1", bytes_type)
|
||||
.build();
|
||||
testlog.info(" schema->version(): {}", schema->version());
|
||||
|
||||
auto reversed_schema = schema->make_reversed();
|
||||
testlog.info(" reversed_schema->version(): {}", reversed_schema->version());
|
||||
|
||||
BOOST_REQUIRE(schema->version() != reversed_schema->version());
|
||||
BOOST_REQUIRE(utils::UUID_gen::negate(schema->version()) == reversed_schema->version());
|
||||
|
||||
auto re_reversed_schema = reversed_schema->make_reversed();
|
||||
testlog.info("re_reversed_schema->version(): {}", re_reversed_schema->version());
|
||||
|
||||
BOOST_REQUIRE(schema->version() == re_reversed_schema->version());
|
||||
BOOST_REQUIRE(reversed_schema->version() != re_reversed_schema->version());
|
||||
|
||||
return make_ready_future<>();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user