| // 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 "olap/block_column_predicate.h" |
| |
| #include <string.h> |
| |
| namespace roaring { |
| class Roaring; |
| } // namespace roaring |
| |
| namespace doris { |
| class WrapperField; |
| namespace segment_v2 { |
| class InvertedIndexIterator; |
| } // namespace segment_v2 |
| |
| uint16_t SingleColumnBlockPredicate::evaluate(vectorized::MutableColumns& block, uint16_t* sel, |
| uint16_t selected_size) const { |
| auto column_id = _predicate->column_id(); |
| auto& column = block[column_id]; |
| return _predicate->evaluate(*column, sel, selected_size); |
| } |
| |
| void SingleColumnBlockPredicate::evaluate_and(vectorized::MutableColumns& block, uint16_t* sel, |
| uint16_t selected_size, bool* flags) const { |
| auto column_id = _predicate->column_id(); |
| auto& column = block[column_id]; |
| _predicate->evaluate_and(*column, sel, selected_size, flags); |
| } |
| |
| bool SingleColumnBlockPredicate::evaluate_and( |
| const std::pair<WrapperField*, WrapperField*>& statistic) const { |
| return _predicate->evaluate_and(statistic); |
| } |
| |
| bool SingleColumnBlockPredicate::evaluate_and(const segment_v2::BloomFilter* bf) const { |
| return _predicate->evaluate_and(bf); |
| } |
| |
| bool SingleColumnBlockPredicate::evaluate_and(const StringRef* dict_words, |
| const size_t dict_num) const { |
| return _predicate->evaluate_and(dict_words, dict_num); |
| } |
| |
| void SingleColumnBlockPredicate::evaluate_or(vectorized::MutableColumns& block, uint16_t* sel, |
| uint16_t selected_size, bool* flags) const { |
| auto column_id = _predicate->column_id(); |
| auto& column = block[column_id]; |
| _predicate->evaluate_or(*column, sel, selected_size, flags); |
| } |
| |
| void SingleColumnBlockPredicate::evaluate_vec(vectorized::MutableColumns& block, uint16_t size, |
| bool* flags) const { |
| auto column_id = _predicate->column_id(); |
| auto& column = block[column_id]; |
| |
| // Dictionary column should do something to initial. |
| if (PredicateTypeTraits::is_range(_predicate->type())) { |
| column->convert_dict_codes_if_necessary(); |
| } else if (PredicateTypeTraits::is_bloom_filter(_predicate->type())) { |
| column->initialize_hash_values_for_runtime_filter(); |
| } |
| |
| _predicate->evaluate_vec(*column, size, flags); |
| } |
| |
| uint16_t OrBlockColumnPredicate::evaluate(vectorized::MutableColumns& block, uint16_t* sel, |
| uint16_t selected_size) const { |
| if (num_of_column_predicate() == 1) { |
| return _block_column_predicate_vec[0]->evaluate(block, sel, selected_size); |
| } else { |
| if (!selected_size) { |
| return 0; |
| } |
| std::vector<uint8_t> ret_flags(selected_size, 0); |
| for (int i = 0; i < num_of_column_predicate(); ++i) { |
| _block_column_predicate_vec[i]->evaluate_or(block, sel, selected_size, |
| (bool*)ret_flags.data()); |
| } |
| |
| uint16_t new_size = 0; |
| for (int i = 0; i < selected_size; ++i) { |
| if (ret_flags[i]) { |
| sel[new_size++] = sel[i]; |
| } |
| } |
| return new_size; |
| } |
| } |
| |
| void OrBlockColumnPredicate::evaluate_or(vectorized::MutableColumns& block, uint16_t* sel, |
| uint16_t selected_size, bool* flags) const { |
| for (auto& block_column_predicate : _block_column_predicate_vec) { |
| block_column_predicate->evaluate_or(block, sel, selected_size, flags); |
| } |
| } |
| |
| void OrBlockColumnPredicate::evaluate_and(vectorized::MutableColumns& block, uint16_t* sel, |
| uint16_t selected_size, bool* flags) const { |
| if (num_of_column_predicate() == 1) { |
| _block_column_predicate_vec[0]->evaluate_and(block, sel, selected_size, flags); |
| } else { |
| std::vector<uint8_t> ret_flags(selected_size, 0); |
| for (int i = 0; i < num_of_column_predicate(); ++i) { |
| _block_column_predicate_vec[i]->evaluate_or(block, sel, selected_size, |
| (bool*)ret_flags.data()); |
| } |
| |
| for (int i = 0; i < selected_size; ++i) { |
| flags[i] &= ret_flags[i]; |
| } |
| } |
| } |
| |
| uint16_t AndBlockColumnPredicate::evaluate(vectorized::MutableColumns& block, uint16_t* sel, |
| uint16_t selected_size) const { |
| for (auto& block_column_predicate : _block_column_predicate_vec) { |
| selected_size = block_column_predicate->evaluate(block, sel, selected_size); |
| } |
| return selected_size; |
| } |
| |
| void AndBlockColumnPredicate::evaluate_and(vectorized::MutableColumns& block, uint16_t* sel, |
| uint16_t selected_size, bool* flags) const { |
| for (auto& block_column_predicate : _block_column_predicate_vec) { |
| block_column_predicate->evaluate_and(block, sel, selected_size, flags); |
| } |
| } |
| |
| bool AndBlockColumnPredicate::evaluate_and( |
| const std::pair<WrapperField*, WrapperField*>& statistic) const { |
| for (auto& block_column_predicate : _block_column_predicate_vec) { |
| if (!block_column_predicate->evaluate_and(statistic)) { |
| return false; |
| } |
| } |
| return true; |
| } |
| |
| bool AndBlockColumnPredicate::evaluate_and(const segment_v2::BloomFilter* bf) const { |
| for (auto& block_column_predicate : _block_column_predicate_vec) { |
| if (!block_column_predicate->evaluate_and(bf)) { |
| return false; |
| } |
| } |
| return true; |
| } |
| |
| bool AndBlockColumnPredicate::evaluate_and(const StringRef* dict_words, |
| const size_t dict_num) const { |
| for (auto& predicate : _block_column_predicate_vec) { |
| if (!predicate->evaluate_and(dict_words, dict_num)) { |
| return false; |
| } |
| } |
| return true; |
| } |
| |
| void AndBlockColumnPredicate::evaluate_or(vectorized::MutableColumns& block, uint16_t* sel, |
| uint16_t selected_size, bool* flags) const { |
| if (num_of_column_predicate() == 1) { |
| _block_column_predicate_vec[0]->evaluate_or(block, sel, selected_size, flags); |
| } else { |
| std::vector<uint8_t> new_flags(selected_size, 1); |
| for (const auto& block_column_predicate : _block_column_predicate_vec) { |
| block_column_predicate->evaluate_and(block, sel, selected_size, |
| (bool*)new_flags.data()); |
| } |
| |
| for (uint16_t i = 0; i < selected_size; i++) { |
| flags[i] |= new_flags[i]; |
| } |
| } |
| } |
| |
| // todo(wb) Can the 'and' of multiple bitmaps be vectorized? |
| void AndBlockColumnPredicate::evaluate_vec(vectorized::MutableColumns& block, uint16_t size, |
| bool* flags) const { |
| if (num_of_column_predicate() == 1) { |
| _block_column_predicate_vec[0]->evaluate_vec(block, size, flags); |
| } else { |
| std::vector<uint8_t> new_flags(size); |
| |
| bool initialized = false; |
| for (const auto& block_column_predicate : _block_column_predicate_vec) { |
| if (initialized) { |
| block_column_predicate->evaluate_vec(block, size, (bool*)new_flags.data()); |
| for (uint16_t j = 0; j < size; j++) { |
| flags[j] &= new_flags[j]; |
| } |
| } else { |
| block_column_predicate->evaluate_vec(block, size, flags); |
| initialized = true; |
| } |
| } |
| } |
| } |
| |
| Status AndBlockColumnPredicate::evaluate(const std::string& column_name, |
| InvertedIndexIterator* iterator, uint32_t num_rows, |
| roaring::Roaring* bitmap) const { |
| return Status::Error<ErrorCode::INVERTED_INDEX_NOT_IMPLEMENTED>( |
| "Not Implemented evaluate with inverted index, please check the predicate"); |
| } |
| |
| } // namespace doris |