be/src/storage/olap_common.h
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 | | #pragma once |
19 | | |
20 | | #include <gen_cpp/Types_types.h> |
21 | | #include <netinet/in.h> |
22 | | |
23 | | #include <atomic> |
24 | | #include <charconv> |
25 | | #include <cstdint> |
26 | | #include <functional> |
27 | | #include <list> |
28 | | #include <map> |
29 | | #include <memory> |
30 | | #include <ostream> |
31 | | #include <sstream> |
32 | | #include <string> |
33 | | #include <typeinfo> |
34 | | #include <unordered_map> |
35 | | #include <unordered_set> |
36 | | #include <utility> |
37 | | |
38 | | #include "common/cast_set.h" |
39 | | #include "common/config.h" |
40 | | #include "common/exception.h" |
41 | | #include "core/extended_types.h" |
42 | | #include "io/io_common.h" |
43 | | #include "storage/field_type.h" |
44 | | #include "storage/index/inverted/common/inverted_index_stats.h" |
45 | | #include "storage/index/inverted/common/snii_query_stats.h" |
46 | | #include "storage/olap_define.h" |
47 | | #include "storage/rowset/rowset_fwd.h" |
48 | | #include "storage/rowset_id.h" |
49 | | #include "util/hash_util.hpp" |
50 | | #include "util/time.h" |
51 | | #include "util/uid_util.h" |
52 | | |
53 | | namespace doris { |
54 | | namespace io { |
55 | | struct ReadAheadStatistics; |
56 | | } |
57 | | |
58 | | using SchemaHash = int32_t; |
59 | | |
60 | | using TabletUid = UniqueId; |
61 | | |
62 | | enum class CompactionType { |
63 | | BASE_COMPACTION = 1, |
64 | | CUMULATIVE_COMPACTION = 2, |
65 | | FULL_COMPACTION = 3, |
66 | | // Only used by scheduler to route changelog tablets to the changelog thread pool. |
67 | | CHANGELOG_COMPACTION = 4 |
68 | | }; |
69 | | |
70 | | inline constexpr CompactionType BASE_COMPACTION = CompactionType::BASE_COMPACTION; |
71 | | inline constexpr CompactionType CUMULATIVE_COMPACTION = CompactionType::CUMULATIVE_COMPACTION; |
72 | | inline constexpr CompactionType FULL_COMPACTION = CompactionType::FULL_COMPACTION; |
73 | | inline constexpr CompactionType CHANGELOG_COMPACTION = CompactionType::CHANGELOG_COMPACTION; |
74 | | |
75 | 66 | inline std::ostream& operator<<(std::ostream& os, CompactionType type) { |
76 | 66 | return os << static_cast<int>(type); |
77 | 66 | } |
78 | | |
79 | | struct CompactionScoreStats { |
80 | | int64_t max_score = 0; |
81 | | int64_t size_based_max_score = 0; |
82 | | int64_t time_series_max_score = 0; |
83 | | bool scanned = false; |
84 | | }; |
85 | | |
86 | | enum class DataDirType { |
87 | | SPILL_DISK_DIR, |
88 | | OLAP_DATA_DIR, |
89 | | DATA_CACHE_DIR, |
90 | | }; |
91 | | |
92 | | struct DataDirInfo { |
93 | | std::string path; |
94 | | size_t path_hash = 0; |
95 | | int64_t disk_capacity = 1; // actual disk capacity |
96 | | int64_t available = 0; // available space, in bytes unit |
97 | | int64_t local_used_capacity = 0; |
98 | | int64_t remote_used_capacity = 0; |
99 | | int64_t trash_used_capacity = 0; |
100 | | bool is_used = false; // whether available mark |
101 | | TStorageMedium::type storage_medium = TStorageMedium::HDD; // Storage medium type: SSD|HDD |
102 | | DataDirType data_dir_type = DataDirType::OLAP_DATA_DIR; |
103 | | std::string metric_name; |
104 | | }; |
105 | | |
106 | | // Sort DataDirInfo by available space. |
107 | | struct DataDirInfoLessAvailability { |
108 | 23 | bool operator()(const DataDirInfo& left, const DataDirInfo& right) const { |
109 | 23 | return left.available < right.available; |
110 | 23 | } |
111 | | }; |
112 | | |
113 | | struct TabletInfo { |
114 | | TabletInfo(TTabletId in_tablet_id, UniqueId in_uid) |
115 | 1.94M | : tablet_id(in_tablet_id), tablet_uid(in_uid) {} |
116 | | |
117 | 10.7M | bool operator<(const TabletInfo& right) const { |
118 | 10.7M | if (tablet_id != right.tablet_id) { |
119 | 10.7M | return tablet_id < right.tablet_id; |
120 | 10.7M | } else { |
121 | 13.1k | return tablet_uid < right.tablet_uid; |
122 | 13.1k | } |
123 | 10.7M | } |
124 | | |
125 | 69 | std::string to_string() const { |
126 | 69 | std::stringstream ss; |
127 | 69 | ss << tablet_id << "." << tablet_uid.to_string(); |
128 | 69 | return ss.str(); |
129 | 69 | } |
130 | | |
131 | | TTabletId tablet_id; |
132 | | UniqueId tablet_uid; |
133 | | }; |
134 | | |
135 | | struct TabletSize { |
136 | | TabletSize(TTabletId in_tablet_id, size_t in_tablet_size) |
137 | 0 | : tablet_id(in_tablet_id), tablet_size(in_tablet_size) {} |
138 | | |
139 | | TTabletId tablet_id; |
140 | | size_t tablet_size; |
141 | | }; |
142 | | |
143 | | // FieldType moved to storage/field_type.h (included above) so that |
144 | | // data-type headers can name storage cell types without pulling in the |
145 | | // whole of olap_common.h. |
146 | | |
147 | | // Define all aggregation methods supported by TabletColumn |
148 | | // Note that in practice, not all types can use all the following aggregation methods |
149 | | // For example, it is meaningless to use SUM for the string type (but it will not cause the program to crash) |
150 | | // The implementation of the TabletColumn class does not perform such checks, and should be constrained when creating the table |
151 | | enum class FieldAggregationMethod { |
152 | | OLAP_FIELD_AGGREGATION_NONE = 0, |
153 | | OLAP_FIELD_AGGREGATION_SUM = 1, |
154 | | OLAP_FIELD_AGGREGATION_MIN = 2, |
155 | | OLAP_FIELD_AGGREGATION_MAX = 3, |
156 | | OLAP_FIELD_AGGREGATION_REPLACE = 4, |
157 | | OLAP_FIELD_AGGREGATION_HLL_UNION = 5, |
158 | | OLAP_FIELD_AGGREGATION_UNKNOWN = 6, |
159 | | OLAP_FIELD_AGGREGATION_BITMAP_UNION = 7, |
160 | | // Replace if and only if added value is not null |
161 | | OLAP_FIELD_AGGREGATION_REPLACE_IF_NOT_NULL = 8, |
162 | | OLAP_FIELD_AGGREGATION_QUANTILE_UNION = 9, |
163 | | OLAP_FIELD_AGGREGATION_GENERIC = 10 |
164 | | }; |
165 | | |
166 | | enum class PushType { |
167 | | PUSH_NORMAL = 1, // for broker/hadoop load, not used any more |
168 | | PUSH_FOR_DELETE = 2, // for delete |
169 | | PUSH_FOR_LOAD_DELETE = 3, // not used any more |
170 | | PUSH_NORMAL_V2 = 4, // for spark load |
171 | | }; |
172 | | |
173 | | // <start_version_id, end_version_id>, such as <100, 110> |
174 | | //using Version = std::pair<TupleVersion, TupleVersion>; |
175 | | |
176 | | struct Version { |
177 | | int64_t first; |
178 | | int64_t second; |
179 | | |
180 | 93.4M | Version(int64_t first_, int64_t second_) : first(first_), second(second_) {} |
181 | 10.0M | Version() : first(0), second(0) {} |
182 | | |
183 | 8.48k | static Version mock() { |
184 | | // Every time SchemaChange is used for external rowing, some temporary versions (such as 999, 1000, 1001) will be written, in order to avoid Cache conflicts, temporary |
185 | | // The version number takes a BIG NUMBER plus the version number of the current SchemaChange |
186 | 8.48k | return Version(1 << 28, 1 << 29); |
187 | 8.48k | } |
188 | | |
189 | | friend std::ostream& operator<<(std::ostream& os, const Version& version); |
190 | | |
191 | 2.20k | bool operator!=(const Version& rhs) const { return first != rhs.first || second != rhs.second; } |
192 | | |
193 | 7.93M | bool operator==(const Version& rhs) const { return first == rhs.first && second == rhs.second; } |
194 | | |
195 | 184k | bool contains(const Version& other) const { |
196 | 184k | return first <= other.first && second >= other.second; |
197 | 184k | } |
198 | | |
199 | 1.37M | std::string to_string() const { return fmt::format("[{}-{}]", first, second); } |
200 | | }; |
201 | | |
202 | | struct TsoRange : public Version { |
203 | 6.97M | TsoRange() : Version(-1, -1) {} |
204 | 7.50M | TsoRange(int64_t start_tso, int64_t end_tso) : Version(start_tso, end_tso) {} |
205 | | |
206 | 1.63M | int64_t start_tso() const { return first; } |
207 | 1.63M | int64_t end_tso() const { return second; } |
208 | | |
209 | 0 | bool contains(const TsoRange& other) const { return Version::contains(other); } |
210 | | }; |
211 | | |
212 | | using Versions = std::vector<Version>; |
213 | | |
214 | 15.5k | inline std::ostream& operator<<(std::ostream& os, const Version& version) { |
215 | 15.5k | return os << version.to_string(); |
216 | 15.5k | } |
217 | | |
218 | 0 | inline std::ostream& operator<<(std::ostream& os, const Versions& versions) { |
219 | 0 | for (auto& version : versions) { |
220 | 0 | os << version; |
221 | 0 | } |
222 | 0 | return os; |
223 | 0 | } |
224 | | |
225 | | // used for hash-struct of hash_map<Version, Rowset*>. |
226 | | struct HashOfVersion { |
227 | 9.28M | size_t operator()(const Version& version) const { |
228 | 9.28M | size_t seed = 0; |
229 | 9.28M | seed = HashUtil::hash64(&version.first, sizeof(version.first), seed); |
230 | 9.28M | seed = HashUtil::hash64(&version.second, sizeof(version.second), seed); |
231 | 9.28M | return seed; |
232 | 9.28M | } |
233 | | }; |
234 | | |
235 | | // It is used to represent Graph vertex. |
236 | | struct Vertex { |
237 | | int64_t value = 0; |
238 | | std::list<int64_t> edges; |
239 | | |
240 | 1.30M | Vertex(int64_t v) : value(v) {} |
241 | | }; |
242 | | |
243 | | // ReaderStatistics used to collect statistics when scan data from storage |
244 | | struct OlapReaderStatistics { |
245 | | int64_t io_ns = 0; |
246 | | int64_t compressed_bytes_read = 0; |
247 | | |
248 | | int64_t decompress_ns = 0; |
249 | | int64_t uncompressed_bytes_read = 0; |
250 | | |
251 | | // total read bytes in memory |
252 | | int64_t bytes_read = 0; |
253 | | |
254 | | int64_t block_fetch_ns = 0; // time of rowset reader's `next_batch()` call |
255 | | int64_t block_load_ns = 0; |
256 | | int64_t blocks_load = 0; |
257 | | // Not used any more, will be removed after non-vectorized code is removed |
258 | | int64_t block_seek_num = 0; |
259 | | // Not used any more, will be removed after non-vectorized code is removed |
260 | | int64_t block_seek_ns = 0; |
261 | | |
262 | | // block_load_ns |
263 | | // block_init_ns |
264 | | // block_init_seek_ns |
265 | | // generate_row_ranges_ns |
266 | | // predicate_column_read_ns |
267 | | // predicate_column_read_seek_ns |
268 | | // lazy_read_ns |
269 | | // block_lazy_read_seek_ns |
270 | | int64_t block_init_ns = 0; |
271 | | int64_t block_init_seek_num = 0; |
272 | | int64_t block_init_seek_ns = 0; |
273 | | int64_t predicate_column_read_ns = 0; |
274 | | int64_t non_predicate_read_ns = 0; |
275 | | int64_t predicate_column_read_seek_num = 0; |
276 | | int64_t predicate_column_read_seek_ns = 0; |
277 | | int64_t lazy_read_ns = 0; |
278 | | int64_t block_lazy_read_seek_num = 0; |
279 | | int64_t block_lazy_read_seek_ns = 0; |
280 | | int64_t lazy_read_pruned_ns = 0; |
281 | | |
282 | | int64_t raw_rows_read = 0; |
283 | | |
284 | | int64_t rows_vec_cond_filtered = 0; |
285 | | int64_t rows_short_circuit_cond_filtered = 0; |
286 | | int64_t rows_expr_cond_filtered = 0; |
287 | | int64_t vec_cond_input_rows = 0; |
288 | | int64_t short_circuit_cond_input_rows = 0; |
289 | | int64_t expr_cond_input_rows = 0; |
290 | | int64_t rows_vec_del_cond_filtered = 0; |
291 | | int64_t vec_cond_ns = 0; |
292 | | int64_t short_cond_ns = 0; |
293 | | int64_t expr_filter_ns = 0; |
294 | | int64_t output_col_ns = 0; |
295 | | int64_t rows_key_range_filtered = 0; |
296 | | int64_t rows_stats_filtered = 0; |
297 | | int64_t rows_stats_rp_filtered = 0; |
298 | | int64_t expr_zonemap_filtered_segments = 0; |
299 | | int64_t expr_zonemap_filtered_pages = 0; |
300 | | int64_t expr_zonemap_unusable_evals = 0; |
301 | | int64_t in_zonemap_point_check_count = 0; |
302 | | int64_t in_zonemap_range_only_count = 0; |
303 | | int64_t rows_bf_filtered = 0; |
304 | | int64_t segment_dict_filtered = 0; |
305 | | // Including the number of rows filtered out according to the Delete information in the Tablet, |
306 | | // and the number of rows filtered for marked deleted rows under the unique key model. |
307 | | // This metric is mainly used to record the number of rows filtered by the delete condition in Segment V1, |
308 | | // and it is also used to record the replaced rows in the Unique key model in the "Reader" class. |
309 | | // In segmentv2, if you want to get all filtered rows, you need the sum of "rows_del_filtered" and "rows_conditions_filtered". |
310 | | int64_t rows_del_filtered = 0; |
311 | | int64_t rows_del_by_bitmap = 0; |
312 | | // the number of rows filtered by various column indexes. |
313 | | int64_t rows_conditions_filtered = 0; |
314 | | int64_t generate_row_ranges_by_keys_ns = 0; |
315 | | int64_t generate_row_ranges_by_column_conditions_ns = 0; |
316 | | int64_t generate_row_ranges_by_bf_ns = 0; |
317 | | int64_t generate_row_ranges_by_zonemap_ns = 0; |
318 | | int64_t generate_row_ranges_by_dict_ns = 0; |
319 | | |
320 | | int64_t index_load_ns = 0; |
321 | | |
322 | | int64_t total_pages_num = 0; |
323 | | int64_t cached_pages_num = 0; |
324 | | |
325 | | int64_t rows_inverted_index_filtered = 0; |
326 | | int64_t inverted_index_filter_timer = 0; |
327 | | int64_t inverted_index_query_timer = 0; |
328 | | int64_t inverted_index_query_cache_hit = 0; |
329 | | int64_t inverted_index_query_cache_miss = 0; |
330 | | int64_t inverted_index_query_cache_lookup = 0; |
331 | | int64_t inverted_index_query_cache_insert = 0; |
332 | | int64_t inverted_index_query_null_bitmap_timer = 0; |
333 | | int64_t inverted_index_query_bitmap_copy_timer = 0; |
334 | | int64_t inverted_index_searcher_open_timer = 0; |
335 | | int64_t inverted_index_searcher_search_timer = 0; |
336 | | int64_t inverted_index_searcher_search_init_timer = 0; |
337 | | int64_t inverted_index_searcher_search_exec_timer = 0; |
338 | | int64_t inverted_index_searcher_cache_hit = 0; |
339 | | int64_t inverted_index_searcher_cache_miss = 0; |
340 | | int64_t inverted_index_downgrade_count = 0; |
341 | | // Pushed-down conjuncts skipped (never index-evaluated) because the row |
342 | | // bitmap was already empty when their turn came. |
343 | | int64_t inverted_index_conjuncts_short_circuited = 0; |
344 | | // Rows pruned by the approximate (gram) index: rows removed when the candidate bitmap is |
345 | | // intersected with _row_bitmap. |
346 | | int64_t rows_gram_index_filtered = 0; |
347 | | // Candidate rows produced by the approximate (gram) index: rows that still need expression |
348 | | // re-verification after the intersection. |
349 | | int64_t gram_index_candidate_rows = 0; |
350 | | // Query nodes the gram index's cost gate widened to the whole segment rather than read. A |
351 | | // non-zero count is why the two numbers above can show an index that eliminated nothing: it |
352 | | // was not consulted for those nodes, by a cost decision rather than because no gram matched. |
353 | | int64_t gram_index_gate_gave_up = 0; |
354 | | int64_t inverted_index_analyzer_timer = 0; |
355 | | int64_t inverted_index_lookup_timer = 0; |
356 | | // See snii_query_stats.h: one field here instead of one per SNII counter. |
357 | | snii::SniiQueryStats snii_stats; |
358 | | InvertedIndexStatistics inverted_index_stats; |
359 | | |
360 | | int64_t ann_index_load_ns = 0; |
361 | | int64_t ann_topn_search_ns = 0; |
362 | | int64_t ann_index_topn_search_cnt = 0; |
363 | | int64_t ann_ivf_on_disk_load_ns = 0; |
364 | | int64_t ann_ivf_on_disk_cache_hit_cnt = 0; |
365 | | int64_t ann_ivf_on_disk_cache_miss_cnt = 0; |
366 | | int64_t ann_index_cache_hits = 0; |
367 | | |
368 | | // Detailed timing for ANN operations |
369 | | int64_t ann_index_topn_engine_search_ns = 0; // time spent in engine for range search |
370 | | int64_t ann_index_topn_result_process_ns = 0; // time spent processing TopN results |
371 | | int64_t ann_index_topn_engine_convert_ns = 0; // time spent on FAISS-side conversions (TopN) |
372 | | int64_t ann_index_topn_engine_prepare_ns = |
373 | | 0; // time spent preparing before engine search (TopN) |
374 | | int64_t rows_ann_index_topn_filtered = 0; |
375 | | |
376 | | int64_t ann_index_range_search_ns = 0; |
377 | | int64_t ann_index_range_search_cnt = 0; |
378 | | // Detailed timing for ANN Range search |
379 | | int64_t ann_range_engine_search_ns = 0; // time spent in engine for range search |
380 | | int64_t ann_range_pre_process_ns = 0; // time spent preparing before engine search |
381 | | |
382 | | int64_t ann_range_result_convert_ns = 0; // time spent processing range results |
383 | | int64_t ann_range_engine_convert_ns = 0; // time spent on FAISS-side conversions (Range) |
384 | | int64_t rows_ann_index_range_filtered = 0; |
385 | | int64_t ann_index_range_cache_hits = 0; |
386 | | int64_t ann_fall_back_brute_force_cnt = 0; |
387 | | int64_t ann_topn_fallback_by_small_candidate_cnt = 0; |
388 | | int64_t ann_topn_fallback_small_candidate_rows = 0; |
389 | | int64_t ann_range_fallback_by_small_candidate_cnt = 0; |
390 | | int64_t ann_range_fallback_small_candidate_rows = 0; |
391 | | |
392 | | int64_t output_index_result_column_timer = 0; |
393 | | // number of segment filtered by column stat when creating seg iterator |
394 | | int64_t filtered_segment_number = 0; |
395 | | // number of condition cache lookups, including misses |
396 | | int64_t condition_cache_lookup_count = 0; |
397 | | // number of segment with condition cache hit |
398 | | int64_t condition_cache_hit_seg_nums = 0; |
399 | | // number of rows filtered by condition cache hit |
400 | | int64_t condition_cache_filtered_rows = 0; |
401 | | // total number of segment |
402 | | int64_t total_segment_number = 0; |
403 | | |
404 | | io::FileCacheStatistics file_cache_stats; |
405 | | // Shared with range tasks so asynchronous completion never writes into this reader's lifetime. |
406 | | std::shared_ptr<io::ReadAheadStatistics> read_ahead_stats; |
407 | | int64_t load_segments_timer = 0; |
408 | | |
409 | | int64_t collect_iterator_merge_next_timer = 0; |
410 | | int64_t collect_iterator_normal_next_timer = 0; |
411 | | int64_t delete_bitmap_get_agg_ns = 0; |
412 | | |
413 | | int64_t tablet_reader_init_timer_ns = 0; |
414 | | int64_t tablet_reader_capture_rs_readers_timer_ns = 0; |
415 | | int64_t tablet_reader_init_keys_param_timer_ns = 0; |
416 | | int64_t tablet_reader_init_orderby_keys_param_timer_ns = 0; |
417 | | int64_t tablet_reader_init_conditions_param_timer_ns = 0; |
418 | | int64_t tablet_reader_init_delete_condition_param_timer_ns = 0; |
419 | | int64_t block_reader_vcollect_iter_init_timer_ns = 0; |
420 | | int64_t block_reader_rs_readers_init_timer_ns = 0; |
421 | | int64_t block_reader_build_heap_init_timer_ns = 0; |
422 | | |
423 | | int64_t rowset_reader_get_segment_iterators_timer_ns = 0; |
424 | | int64_t rowset_reader_create_iterators_timer_ns = 0; |
425 | | int64_t rowset_reader_init_iterators_timer_ns = 0; |
426 | | int64_t rowset_reader_load_segments_timer_ns = 0; |
427 | | |
428 | | int64_t segment_iterator_init_timer_ns = 0; |
429 | | int64_t segment_iterator_init_column_iterators_timer_ns = 0; |
430 | | int64_t segment_iterator_init_index_iterators_timer_ns = 0; |
431 | | int64_t segment_iterator_init_segment_prefetchers_timer_ns = 0; |
432 | | |
433 | | int64_t segment_create_column_readers_timer_ns = 0; |
434 | | int64_t segment_load_index_timer_ns = 0; |
435 | | |
436 | | int64_t adaptive_batch_size_predict_min_rows = INT64_MAX; |
437 | | int64_t adaptive_batch_size_predict_max_rows = 0; |
438 | | |
439 | | int64_t variant_scan_sparse_column_timer_ns = 0; |
440 | | int64_t variant_scan_sparse_column_bytes = 0; |
441 | | int64_t variant_fill_path_from_sparse_column_timer_ns = 0; |
442 | | int64_t variant_subtree_default_iter_count = 0; |
443 | | int64_t variant_subtree_leaf_iter_count = 0; |
444 | | int64_t variant_subtree_hierarchical_iter_count = 0; |
445 | | int64_t variant_subtree_sparse_iter_count = 0; |
446 | | int64_t variant_doc_value_column_iter_count = 0; |
447 | | }; |
448 | | |
449 | | using ColumnId = uint32_t; |
450 | | // Column unique id set |
451 | | using UniqueIdSet = std::set<uint32_t>; |
452 | | // Column unique Id -> column id map |
453 | | using UniqueIdToColumnIdMap = std::map<ColumnId, ColumnId>; |
454 | | |
455 | | // RowsetId moved to storage/rowset_id.h (included above): core/column/column.h |
456 | | // needs the complete type, and this way it gets it without the rest of |
457 | | // olap_common.h. |
458 | | |
459 | | using RowsetIdUnorderedSet = std::unordered_set<RowsetId>; |
460 | | |
461 | | // Extract rowset id from filename, return uninitialized rowset id if filename is invalid |
462 | 82.4k | inline RowsetId extract_rowset_id(std::string_view filename) { |
463 | 82.4k | RowsetId rowset_id; |
464 | 82.4k | if (filename.ends_with(".dat")) { |
465 | | // filename format: {rowset_id}_{segment_num}.dat |
466 | 76.4k | auto end = filename.find('_'); |
467 | 76.4k | if (end == std::string::npos) { |
468 | 0 | return rowset_id; |
469 | 0 | } |
470 | 76.4k | rowset_id.init(filename.substr(0, end)); |
471 | 76.4k | return rowset_id; |
472 | 76.4k | } |
473 | 6.00k | if (filename.ends_with(".idx")) { |
474 | | // filename format: {rowset_id}_{segment_num}_{index_id}.idx |
475 | 5.81k | auto end = filename.find('_'); |
476 | 5.81k | if (end == std::string::npos) { |
477 | 0 | return rowset_id; |
478 | 0 | } |
479 | 5.81k | rowset_id.init(filename.substr(0, end)); |
480 | 5.81k | return rowset_id; |
481 | 5.81k | } |
482 | 184 | return rowset_id; |
483 | 6.00k | } |
484 | | |
485 | | class DeleteBitmap; |
486 | | // merge on write context |
487 | | struct MowContext { |
488 | | MowContext(int64_t version, int64_t txnid, std::shared_ptr<RowsetIdUnorderedSet> ids, |
489 | | std::vector<RowsetSharedPtr> rowset_ptrs, std::shared_ptr<DeleteBitmap> db) |
490 | 61.7k | : max_version(version), |
491 | 61.7k | txn_id(txnid), |
492 | 61.7k | rowset_ids(std::move(ids)), |
493 | 61.7k | rowset_ptrs(std::move(rowset_ptrs)), |
494 | 61.7k | delete_bitmap(std::move(db)) {} |
495 | | int64_t max_version; |
496 | | int64_t txn_id; |
497 | | std::shared_ptr<RowsetIdUnorderedSet> rowset_ids; |
498 | | std::vector<RowsetSharedPtr> rowset_ptrs; |
499 | | std::shared_ptr<DeleteBitmap> delete_bitmap; |
500 | | }; |
501 | | |
502 | | // used for controll compaction |
503 | | struct VersionWithTime { |
504 | | std::atomic<int64_t> version; |
505 | | int64_t update_ts; |
506 | | |
507 | 40.6k | VersionWithTime() : version(0), update_ts(MonotonicMillis()) {} |
508 | | |
509 | 38.0k | void update_version_monoto(int64_t new_version) { |
510 | 38.0k | int64_t cur_version = version.load(std::memory_order_relaxed); |
511 | 38.0k | while (cur_version < new_version) { |
512 | 38.0k | if (version.compare_exchange_strong(cur_version, new_version, std::memory_order_relaxed, |
513 | 38.0k | std::memory_order_relaxed)) { |
514 | 38.0k | update_ts = MonotonicMillis(); |
515 | 38.0k | break; |
516 | 38.0k | } |
517 | 38.0k | } |
518 | 38.0k | } |
519 | | }; |
520 | | } // namespace doris |