blob: 6c78babf7911d44caba1d66cca64a71498042d5a [file] [log] [blame]
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
#include "kudu/common/predicate_effectiveness.h"
#include <ostream>
#include <gflags/gflags.h>
#include "kudu/common/iterator_stats.h"
#include "kudu/gutil/macros.h"
#include "kudu/util/flag_tags.h"
using std::pair;
using std::vector;
DEFINE_bool(predicate_effectivess_enabled, true,
"Should ineffective predicate filtering be disabled");
TAG_FLAG(predicate_effectivess_enabled, advanced);
TAG_FLAG(predicate_effectivess_enabled, runtime);
DEFINE_double(predicate_effectivess_reject_ratio, 0.10,
"Rejection ratio below which predicate filter is considered ineffective");
TAG_FLAG(predicate_effectivess_reject_ratio, advanced);
TAG_FLAG(predicate_effectivess_reject_ratio, runtime);
DEFINE_int32(predicate_effectivess_num_skip_blocks, 128,
"Number of blocks to skip for every predicate effectiveness check");
TAG_FLAG(predicate_effectivess_num_skip_blocks, advanced);
TAG_FLAG(predicate_effectivess_num_skip_blocks, runtime);
namespace kudu {
bool IsColumnPredicateDisableable(PredicateType type) {
return FLAGS_predicate_effectivess_enabled &&
type == PredicateType::InBloomFilter;
}
bool PredicateEffectivenessContext::IsPredicateEnabled() const {
return !FLAGS_predicate_effectivess_enabled || enabled;
}
void IteratorPredicateEffectivenessContext::DisableIneffectivePredicates() {
if (!FLAGS_predicate_effectivess_enabled ||
(next_block_count_ % FLAGS_predicate_effectivess_num_skip_blocks) != 0) {
return;
}
for (auto& idx_and_pred_ctx : predicate_ctxs_) {
auto& pred_ctx = idx_and_pred_ctx.second;
DCHECK(IsColumnPredicateDisableable(pred_ctx.pred->predicate_type()));
if (!pred_ctx.enabled) {
// Predicate already disabled.
continue;
}
DCHECK(pred_ctx.rows_read != 0);
auto rejection_ratio = static_cast<double>(pred_ctx.rows_rejected) / pred_ctx.rows_read;
DCHECK_LE(rejection_ratio, 1.0);
if (rejection_ratio < FLAGS_predicate_effectivess_reject_ratio) {
pred_ctx.enabled = false;
VLOG(1) << "Disabling column predicate " << pred_ctx.pred->ToString();
}
}
}
void IteratorPredicateEffectivenessContext::PopulateIteratorStatsWithDisabledPredicates(
const vector<pair<int32_t, ColumnPredicate>>& col_idx_predicates,
vector<IteratorStats>* stats) const {
for (const auto& pred_idx_and_eff_ctx : predicate_ctxs_) {
const auto& pred_idx = pred_idx_and_eff_ctx.first;
const auto& eff_ctx = pred_idx_and_eff_ctx.second;
const auto& col_idx = col_idx_predicates[pred_idx].first;
DCHECK(IsColumnPredicateDisableable(eff_ctx.pred->predicate_type()))
<< "Incorrectly tracked non-disableable predicate: " << eff_ctx.pred->ToString();
DCHECK_LT(col_idx, stats->size());
(*stats)[col_idx].predicates_disabled = !eff_ctx.enabled;
}
}
} // namespace kudu