be/src/storage/predicate/block_column_predicate.cpp
Line | Count | Source |
1 | | // Licensed to the Apache Software Foundation (ASF) under one |
2 | | // or more contributor license agreements. See the NOTICE file |
3 | | // distributed with this work for additional information |
4 | | // regarding copyright ownership. The ASF licenses this file |
5 | | // to you under the Apache License, Version 2.0 (the |
6 | | // "License"); you may not use this file except in compliance |
7 | | // with the License. You may obtain a copy of the License at |
8 | | // |
9 | | // http://www.apache.org/licenses/LICENSE-2.0 |
10 | | // |
11 | | // Unless required by applicable law or agreed to in writing, |
12 | | // software distributed under the License is distributed on an |
13 | | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
14 | | // KIND, either express or implied. See the License for the |
15 | | // specific language governing permissions and limitations |
16 | | // under the License. |
17 | | |
18 | | #include "storage/predicate/block_column_predicate.h" |
19 | | |
20 | | #include <string.h> |
21 | | |
22 | | namespace roaring { |
23 | | class Roaring; |
24 | | } // namespace roaring |
25 | | |
26 | | namespace doris { |
27 | | namespace segment_v2 { |
28 | | class InvertedIndexIterator; |
29 | | } // namespace segment_v2 |
30 | | |
31 | | uint16_t SingleColumnBlockPredicate::evaluate(MutableColumns& block, uint16_t* sel, |
32 | 4.20k | uint16_t selected_size) const { |
33 | 4.20k | auto column_id = _predicate->column_id(); |
34 | 4.20k | auto& column = block[column_id]; |
35 | 4.20k | return _predicate->evaluate(*column, sel, selected_size); |
36 | 4.20k | } |
37 | | |
38 | | void SingleColumnBlockPredicate::evaluate_and(MutableColumns& block, uint16_t* sel, |
39 | 4 | uint16_t selected_size, bool* flags) const { |
40 | 4 | auto column_id = _predicate->column_id(); |
41 | 4 | auto& column = block[column_id]; |
42 | 4 | _predicate->evaluate_and(*column, sel, selected_size, flags); |
43 | 4 | } |
44 | | |
45 | 582 | bool SingleColumnBlockPredicate::evaluate_and(const segment_v2::ZoneMap& zone_map) const { |
46 | 582 | return _predicate->evaluate_and(zone_map); |
47 | 582 | } |
48 | | |
49 | 10 | bool SingleColumnBlockPredicate::evaluate_and(const segment_v2::BloomFilter* bf) const { |
50 | 10 | return _predicate->evaluate_and(bf); |
51 | 10 | } |
52 | | |
53 | | bool SingleColumnBlockPredicate::evaluate_and(const StringRef* dict_words, |
54 | 0 | const size_t dict_num) const { |
55 | 0 | return _predicate->evaluate_and(dict_words, dict_num); |
56 | 0 | } |
57 | | |
58 | | void SingleColumnBlockPredicate::evaluate_or(MutableColumns& block, uint16_t* sel, |
59 | 6 | uint16_t selected_size, bool* flags) const { |
60 | 6 | auto column_id = _predicate->column_id(); |
61 | 6 | auto& column = block[column_id]; |
62 | 6 | _predicate->evaluate_or(*column, sel, selected_size, flags); |
63 | 6 | } |
64 | | |
65 | | void SingleColumnBlockPredicate::evaluate_vec(MutableColumns& block, uint16_t size, |
66 | 0 | bool* flags) const { |
67 | 0 | auto column_id = _predicate->column_id(); |
68 | 0 | auto& column = block[column_id]; |
69 | | |
70 | | // Dictionary column should do something to initial. |
71 | 0 | if (PredicateTypeTraits::is_range(_predicate->type())) { |
72 | 0 | column->convert_dict_codes_if_necessary(); |
73 | 0 | } else if (PredicateTypeTraits::is_bloom_filter(_predicate->type())) { |
74 | 0 | column->initialize_hash_values_for_runtime_filter(); |
75 | 0 | } |
76 | |
|
77 | 0 | _predicate->evaluate_vec(*column, size, flags); |
78 | 0 | } |
79 | | |
80 | | uint16_t OrBlockColumnPredicate::evaluate(MutableColumns& block, uint16_t* sel, |
81 | 4 | uint16_t selected_size) const { |
82 | 4 | if (num_of_column_predicate() == 1) { |
83 | 0 | return _block_column_predicate_vec[0]->evaluate(block, sel, selected_size); |
84 | 4 | } else { |
85 | 4 | if (!selected_size) { |
86 | 0 | return 0; |
87 | 0 | } |
88 | 4 | std::vector<uint8_t> ret_flags(selected_size, 0); |
89 | 12 | for (int i = 0; i < num_of_column_predicate(); ++i) { |
90 | 8 | _block_column_predicate_vec[i]->evaluate_or(block, sel, selected_size, |
91 | 8 | (bool*)ret_flags.data()); |
92 | 8 | } |
93 | | |
94 | 4 | uint16_t new_size = 0; |
95 | 38 | for (int i = 0; i < selected_size; ++i) { |
96 | 34 | if (ret_flags[i]) { |
97 | 23 | sel[new_size++] = sel[i]; |
98 | 23 | } |
99 | 34 | } |
100 | 4 | return new_size; |
101 | 4 | } |
102 | 4 | } |
103 | | |
104 | | void OrBlockColumnPredicate::evaluate_or(MutableColumns& block, uint16_t* sel, |
105 | 0 | uint16_t selected_size, bool* flags) const { |
106 | 0 | for (auto& block_column_predicate : _block_column_predicate_vec) { |
107 | 0 | block_column_predicate->evaluate_or(block, sel, selected_size, flags); |
108 | 0 | } |
109 | 0 | } |
110 | | |
111 | | void OrBlockColumnPredicate::evaluate_and(MutableColumns& block, uint16_t* sel, |
112 | 0 | uint16_t selected_size, bool* flags) const { |
113 | 0 | if (num_of_column_predicate() == 1) { |
114 | 0 | _block_column_predicate_vec[0]->evaluate_and(block, sel, selected_size, flags); |
115 | 0 | } else { |
116 | 0 | std::vector<uint8_t> ret_flags(selected_size, 0); |
117 | 0 | for (int i = 0; i < num_of_column_predicate(); ++i) { |
118 | 0 | _block_column_predicate_vec[i]->evaluate_or(block, sel, selected_size, |
119 | 0 | (bool*)ret_flags.data()); |
120 | 0 | } |
121 | |
|
122 | 0 | for (int i = 0; i < selected_size; ++i) { |
123 | 0 | flags[i] &= ret_flags[i]; |
124 | 0 | } |
125 | 0 | } |
126 | 0 | } |
127 | | |
128 | | bool OrBlockColumnPredicate::evaluate_and(ParquetPredicate::CachedPageIndexStat* statistic, |
129 | 0 | RowRanges* row_ranges) const { |
130 | 0 | if (num_of_column_predicate() >= 1) { |
131 | 0 | _block_column_predicate_vec[0]->evaluate_and(statistic, row_ranges); |
132 | 0 | for (int i = 1; i < num_of_column_predicate(); ++i) { |
133 | 0 | RowRanges tmp_row_ranges; |
134 | 0 | _block_column_predicate_vec[i]->evaluate_and(statistic, &tmp_row_ranges); |
135 | 0 | RowRanges::ranges_union(*row_ranges, tmp_row_ranges, row_ranges); |
136 | 0 | } |
137 | 0 | } |
138 | 0 | return row_ranges->count() != 0; |
139 | 0 | } |
140 | | |
141 | | bool AndBlockColumnPredicate::evaluate_and(ParquetPredicate::CachedPageIndexStat* statistic, |
142 | 0 | RowRanges* row_ranges) const { |
143 | 0 | if (num_of_column_predicate() >= 1) { |
144 | 0 | for (int i = 0; i < num_of_column_predicate(); ++i) { |
145 | 0 | RowRanges tmp_row_ranges; |
146 | 0 | if (!_block_column_predicate_vec[i]->evaluate_and(statistic, &tmp_row_ranges)) { |
147 | 0 | return false; |
148 | 0 | } |
149 | | |
150 | 0 | if (i == 0) { |
151 | 0 | *row_ranges = tmp_row_ranges; |
152 | 0 | } else { |
153 | 0 | RowRanges::ranges_intersection(*row_ranges, tmp_row_ranges, row_ranges); |
154 | 0 | } |
155 | 0 | } |
156 | 0 | } |
157 | 0 | return true; |
158 | 0 | } |
159 | | |
160 | | uint16_t AndBlockColumnPredicate::evaluate(MutableColumns& block, uint16_t* sel, |
161 | 4.20k | uint16_t selected_size) const { |
162 | 4.20k | for (auto& block_column_predicate : _block_column_predicate_vec) { |
163 | 4.20k | selected_size = block_column_predicate->evaluate(block, sel, selected_size); |
164 | 4.20k | } |
165 | 4.20k | return selected_size; |
166 | 4.20k | } |
167 | | |
168 | | void AndBlockColumnPredicate::evaluate_and(MutableColumns& block, uint16_t* sel, |
169 | 0 | uint16_t selected_size, bool* flags) const { |
170 | 0 | for (auto& block_column_predicate : _block_column_predicate_vec) { |
171 | 0 | block_column_predicate->evaluate_and(block, sel, selected_size, flags); |
172 | 0 | } |
173 | 0 | } |
174 | | |
175 | 0 | bool AndBlockColumnPredicate::evaluate_and(const segment_v2::ZoneMap& zone_map) const { |
176 | 0 | for (auto& block_column_predicate : _block_column_predicate_vec) { |
177 | 0 | if (!block_column_predicate->evaluate_and(zone_map)) { |
178 | 0 | return false; |
179 | 0 | } |
180 | 0 | } |
181 | 0 | return true; |
182 | 0 | } |
183 | | |
184 | 0 | bool AndBlockColumnPredicate::evaluate_and(const segment_v2::BloomFilter* bf) const { |
185 | 0 | for (auto& block_column_predicate : _block_column_predicate_vec) { |
186 | 0 | if (!block_column_predicate->evaluate_and(bf)) { |
187 | 0 | return false; |
188 | 0 | } |
189 | 0 | } |
190 | 0 | return true; |
191 | 0 | } |
192 | | |
193 | | bool AndBlockColumnPredicate::evaluate_and(const StringRef* dict_words, |
194 | 0 | const size_t dict_num) const { |
195 | 0 | for (auto& predicate : _block_column_predicate_vec) { |
196 | 0 | if (!predicate->evaluate_and(dict_words, dict_num)) { |
197 | 0 | return false; |
198 | 0 | } |
199 | 0 | } |
200 | 0 | return true; |
201 | 0 | } |
202 | | |
203 | | void AndBlockColumnPredicate::evaluate_or(MutableColumns& block, uint16_t* sel, |
204 | 2 | uint16_t selected_size, bool* flags) const { |
205 | 2 | if (num_of_column_predicate() == 1) { |
206 | 0 | _block_column_predicate_vec[0]->evaluate_or(block, sel, selected_size, flags); |
207 | 2 | } else { |
208 | 2 | std::vector<uint8_t> new_flags(selected_size, 1); |
209 | 4 | for (const auto& block_column_predicate : _block_column_predicate_vec) { |
210 | 4 | block_column_predicate->evaluate_and(block, sel, selected_size, |
211 | 4 | (bool*)new_flags.data()); |
212 | 4 | } |
213 | | |
214 | 16 | for (uint16_t i = 0; i < selected_size; i++) { |
215 | 14 | flags[i] |= new_flags[i]; |
216 | 14 | } |
217 | 2 | } |
218 | 2 | } |
219 | | |
220 | | // todo(wb) Can the 'and' of multiple bitmaps be vectorized? |
221 | | void AndBlockColumnPredicate::evaluate_vec(MutableColumns& block, uint16_t size, |
222 | 0 | bool* flags) const { |
223 | 0 | if (num_of_column_predicate() == 1) { |
224 | 0 | _block_column_predicate_vec[0]->evaluate_vec(block, size, flags); |
225 | 0 | } else { |
226 | 0 | std::vector<uint8_t> new_flags(size); |
227 | |
|
228 | 0 | bool initialized = false; |
229 | 0 | for (const auto& block_column_predicate : _block_column_predicate_vec) { |
230 | 0 | if (initialized) { |
231 | 0 | block_column_predicate->evaluate_vec(block, size, (bool*)new_flags.data()); |
232 | 0 | for (uint16_t j = 0; j < size; j++) { |
233 | 0 | flags[j] &= new_flags[j]; |
234 | 0 | } |
235 | 0 | } else { |
236 | 0 | block_column_predicate->evaluate_vec(block, size, flags); |
237 | 0 | initialized = true; |
238 | 0 | } |
239 | 0 | } |
240 | 0 | } |
241 | 0 | } |
242 | | |
243 | | Status AndBlockColumnPredicate::evaluate(const std::string& column_name, |
244 | | InvertedIndexIterator* iterator, uint32_t num_rows, |
245 | 0 | roaring::Roaring* bitmap) const { |
246 | 0 | return Status::Error<ErrorCode::INVERTED_INDEX_NOT_IMPLEMENTED>( |
247 | 0 | "Not Implemented evaluate with inverted index, please check the predicate"); |
248 | 0 | } |
249 | | |
250 | | } // namespace doris |