view: Carry data_dictionary arg through standalone helpers

There's a bunch of functions in view.{hh|cc} that don't belong to any
class and perform view-related claculations for view updates. Lots of
them eventually call view_info::select_statement() which will later need
the dictionary.

By now all those methods' callers have data dictionary at hand and can
share it via argument.

Signed-off-by: Pavel Emelyanov <xemul@scylladb.com>
This commit is contained in:
Pavel Emelyanov
2023-04-20 09:26:55 +03:00
parent 1301a99ba3
commit 837fde84b1
3 changed files with 23 additions and 21 deletions

View File

@@ -273,7 +273,7 @@ void stats::register_stats() {
});
}
bool partition_key_matches(const schema& base, const view_info& view, const dht::decorated_key& key) {
bool partition_key_matches(data_dictionary::database db, const schema& base, const view_info& view, const dht::decorated_key& key) {
const cql3::expr::expression& pk_restrictions = view.select_statement().get_restrictions()->get_partition_key_restrictions();
std::vector<bytes> exploded_pk = key.key().explode();
std::vector<bytes> exploded_ck;
@@ -298,7 +298,7 @@ bool partition_key_matches(const schema& base, const view_info& view, const dht:
});
}
bool clustering_prefix_matches(const schema& base, const view_info& view, const partition_key& key, const clustering_key_prefix& ck) {
bool clustering_prefix_matches(data_dictionary::database db, const schema& base, const view_info& view, const partition_key& key, const clustering_key_prefix& ck) {
const cql3::expr::expression& r = view.select_statement().get_restrictions()->get_clustering_columns_restrictions();
std::vector<bytes> exploded_pk = key.explode();
std::vector<bytes> exploded_ck = ck.explode();
@@ -322,21 +322,21 @@ bool clustering_prefix_matches(const schema& base, const view_info& view, const
});
}
bool may_be_affected_by(const schema& base, const view_info& view, const dht::decorated_key& key, const rows_entry& update) {
bool may_be_affected_by(data_dictionary::database db, const schema& base, const view_info& view, const dht::decorated_key& key, const rows_entry& update) {
// We can guarantee that the view won't be affected if:
// - the primary key is excluded by the view filter (note that this isn't true of the filter on regular columns:
// even if an update don't match a view condition on a regular column, that update can still invalidate a
// pre-existing entry) - note that the upper layers should already have checked the partition key;
return clustering_prefix_matches(base, view, key.key(), update.key());
return clustering_prefix_matches(db, base, view, key.key(), update.key());
}
static bool update_requires_read_before_write(const schema& base,
static bool update_requires_read_before_write(data_dictionary::database db, const schema& base,
const std::vector<view_and_base>& views,
const dht::decorated_key& key,
const rows_entry& update) {
for (auto&& v : views) {
view_info& vf = *v.view->view_info();
if (may_be_affected_by(base, vf, key, update)) {
if (may_be_affected_by(db, base, vf, key, update)) {
return true;
}
}
@@ -447,7 +447,7 @@ public:
}
};
bool matches_view_filter(const schema& base, const view_info& view, const partition_key& key, const clustering_or_static_row& update, gc_clock::time_point now) {
bool matches_view_filter(data_dictionary::database db, const schema& base, const view_info& view, const partition_key& key, const clustering_or_static_row& update, gc_clock::time_point now) {
// TODO: Filtering is only supported in materialized views which don't support
// static rows yet. Skip the whole function if it is a static row update.
if (update.is_static_row()) {
@@ -464,7 +464,7 @@ bool matches_view_filter(const schema& base, const view_info& view, const partit
view_filter_checking_visitor visitor(base, view);
query::result_view::consume(result, slice, visitor);
return clustering_prefix_matches(base, view, key, *update.key())
return clustering_prefix_matches(db, base, view, key, *update.key())
&& visitor.matches_view_filter();
}
@@ -877,7 +877,7 @@ static void add_cells_to_view(const schema& base, const schema& view, column_kin
* This method checks that the base row does match the view filter before applying anything.
*/
void view_updates::create_entry(data_dictionary::database db, const partition_key& base_key, const clustering_or_static_row& update, gc_clock::time_point now) {
if (!matches_view_filter(*_base, _view_info, base_key, update, now)) {
if (!matches_view_filter(db, *_base, _view_info, base_key, update, now)) {
return;
}
@@ -903,7 +903,7 @@ void view_updates::create_entry(data_dictionary::database db, const partition_ke
void view_updates::delete_old_entry(data_dictionary::database db, const partition_key& base_key, const clustering_or_static_row& existing, const clustering_or_static_row& update, gc_clock::time_point now) {
// Before deleting an old entry, make sure it was matching the view filter
// (otherwise there is nothing to delete)
if (matches_view_filter(*_base, _view_info, base_key, existing, now)) {
if (matches_view_filter(db, *_base, _view_info, base_key, existing, now)) {
do_delete_old_entry(base_key, existing, update, now);
}
}
@@ -1023,11 +1023,11 @@ bool view_updates::can_skip_view_updates(const clustering_or_static_row& update,
void view_updates::update_entry(data_dictionary::database db, const partition_key& base_key, const clustering_or_static_row& update, const clustering_or_static_row& existing, gc_clock::time_point now) {
// While we know update and existing correspond to the same view entry,
// they may not match the view filter.
if (!matches_view_filter(*_base, _view_info, base_key, existing, now)) {
if (!matches_view_filter(db, *_base, _view_info, base_key, existing, now)) {
create_entry(db, base_key, update, now);
return;
}
if (!matches_view_filter(*_base, _view_info, base_key, update, now)) {
if (!matches_view_filter(db, *_base, _view_info, base_key, update, now)) {
do_delete_old_entry(base_key, existing, update, now);
return;
}
@@ -1459,7 +1459,8 @@ view_update_builder make_view_update_builder(
return view_update_builder(std::move(db), base_table, base, std::move(vs), std::move(updates), std::move(existings), now);
}
future<query::clustering_row_ranges> calculate_affected_clustering_ranges(const schema& base,
future<query::clustering_row_ranges> calculate_affected_clustering_ranges(data_dictionary::database db,
const schema& base,
const dht::decorated_key& key,
const mutation_partition& mp,
const std::vector<view_and_base>& views) {
@@ -1498,7 +1499,7 @@ future<query::clustering_row_ranges> calculate_affected_clustering_ranges(const
}
for (auto&& row : mp.clustered_rows()) {
if (update_requires_read_before_write(base, views, key, row)) {
if (update_requires_read_before_write(db, base, views, key, row)) {
row_ranges.emplace_back(row.key());
}
co_await coroutine::maybe_yield();
@@ -2307,7 +2308,7 @@ public:
inject_failure("view_builder_load_views");
for (auto&& vs : _step.build_status) {
if (_step.current_token() >= vs.next_token) {
if (partition_key_matches(*_step.reader.schema(), *vs.view->view_info(), _step.current_key)) {
if (partition_key_matches(_builder.get_db().as_data_dictionary(), *_step.reader.schema(), *vs.view->view_info(), _step.current_key)) {
_views_to_build.push_back(vs.view);
}
if (vs.next_token || _step.current_token() != vs.first_token) {

View File

@@ -125,7 +125,7 @@ public:
* @return false if we can guarantee that inserting an update for specified key
* won't affect the view in any way, true otherwise.
*/
bool partition_key_matches(const schema& base, const view_info& view, const dht::decorated_key& key);
bool partition_key_matches(data_dictionary::database, const schema& base, const view_info& view, const dht::decorated_key& key);
/**
* Whether the view might be affected by the provided update.
@@ -140,7 +140,7 @@ bool partition_key_matches(const schema& base, const view_info& view, const dht:
* @return false if we can guarantee that inserting update for key
* won't affect the view in any way, true otherwise.
*/
bool may_be_affected_by(const schema& base, const view_info& view, const dht::decorated_key& key, const rows_entry& update);
bool may_be_affected_by(data_dictionary::database, const schema& base, const view_info& view, const dht::decorated_key& key, const rows_entry& update);
/**
* Whether a given base row matches the view filter (and thus if the view should have a corresponding entry).
@@ -159,9 +159,9 @@ bool may_be_affected_by(const schema& base, const view_info& view, const dht::de
* @param now the current time in seconds (to decide what is live and what isn't).
* @return whether the base row matches the view filter.
*/
bool matches_view_filter(const schema& base, const view_info& view, const partition_key& key, const clustering_or_static_row& update, gc_clock::time_point now);
bool matches_view_filter(data_dictionary::database, const schema& base, const view_info& view, const partition_key& key, const clustering_or_static_row& update, gc_clock::time_point now);
bool clustering_prefix_matches(const schema& base, const partition_key& key, const clustering_key_prefix& ck);
bool clustering_prefix_matches(data_dictionary::database, const schema& base, const partition_key& key, const clustering_key_prefix& ck);
/*
* When a base-table update modifies a value in a materialized view's key
@@ -310,6 +310,7 @@ view_update_builder make_view_update_builder(
gc_clock::time_point now);
future<query::clustering_row_ranges> calculate_affected_clustering_ranges(
data_dictionary::database db,
const schema& base,
const dht::decorated_key& key,
const mutation_partition& mp,

View File

@@ -1979,7 +1979,7 @@ const std::vector<view_ptr>& table::views() const {
std::vector<view_ptr> table::affected_views(shared_ptr<db::view::view_update_generator> gen, const schema_ptr& base, const mutation& update) const {
//FIXME: Avoid allocating a vector here; consider returning the boost iterator.
return boost::copy_range<std::vector<view_ptr>>(_views | boost::adaptors::filtered([&] (auto&& view) {
return db::view::partition_key_matches(*base, *view->view_info(), update.decorated_key());
return db::view::partition_key_matches(gen->get_db().as_data_dictionary(), *base, *view->view_info(), update.decorated_key());
}));
}
@@ -2640,7 +2640,7 @@ future<row_locker::lock_holder> table::do_push_view_replica_updates(shared_ptr<d
if (views.empty()) {
co_return row_locker::lock_holder();
}
auto cr_ranges = co_await db::view::calculate_affected_clustering_ranges(*base, m.decorated_key(), m.partition(), views);
auto cr_ranges = co_await db::view::calculate_affected_clustering_ranges(gen->get_db().as_data_dictionary(), *base, m.decorated_key(), m.partition(), views);
const bool need_regular = !cr_ranges.empty();
const bool need_static = db::view::needs_static_row(m.partition(), views);
if (!need_regular && !need_static) {