be/src/exec/scan/file_scanner_v2.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 <map> |
21 | | #include <memory> |
22 | | #include <optional> |
23 | | #include <string> |
24 | | #include <unordered_map> |
25 | | #include <vector> |
26 | | |
27 | | #include "common/factory_creator.h" |
28 | | #include "common/status.h" |
29 | | #include "core/block/block.h" |
30 | | #include "exec/operator/file_scan_operator.h" |
31 | | #include "exec/scan/scanner.h" |
32 | | #include "exec/scan/split_source_connector.h" |
33 | | #include "exprs/vexpr_fwd.h" |
34 | | #include "format_v2/column_mapper.h" |
35 | | #include "format_v2/table_reader.h" |
36 | | #include "gen_cpp/Descriptors_types.h" |
37 | | #include "gen_cpp/PlanNodes_types.h" |
38 | | #include "io/io_common.h" |
39 | | #include "runtime/runtime_profile.h" |
40 | | #include "storage/segment/adaptive_block_size_predictor.h" |
41 | | |
42 | | namespace doris { |
43 | | |
44 | | class RuntimeState; |
45 | | class SlotDescriptor; |
46 | | class TFileRangeDesc; |
47 | | class TFileScanRangeParams; |
48 | | class ShardedKVCache; |
49 | | |
50 | | class FileScannerV2 final : public Scanner { |
51 | | ENABLE_FACTORY_CREATOR(FileScannerV2); |
52 | | |
53 | | public: |
54 | | static constexpr const char* NAME = "FileScannerV2"; |
55 | | static constexpr size_t ADAPTIVE_BATCH_INITIAL_PROBE_ROWS = 32; |
56 | | |
57 | | struct RealtimeCounterDeltas { |
58 | | int64_t scan_rows = 0; |
59 | | int64_t scan_bytes = 0; |
60 | | int64_t scan_bytes_from_local_storage = 0; |
61 | | int64_t scan_bytes_from_remote_storage = 0; |
62 | | }; |
63 | | |
64 | | enum class UncachedReaderBytesStorage { LOCAL, REMOTE, NONE }; |
65 | | |
66 | | static bool is_supported(const TFileScanRangeParams& params, const TFileRangeDesc& range); |
67 | | #ifdef BE_TEST |
68 | | static Status TEST_validate_scan_range(const TFileScanRangeParams& params, |
69 | | const TFileRangeDesc& range); |
70 | | static Status TEST_to_file_format(TFileFormatType::type format_type, |
71 | | format::FileFormat* file_format); |
72 | | static bool TEST_is_partition_slot(const TFileScanSlotInfo& slot_info, |
73 | | const std::string& column_name); |
74 | | static bool TEST_is_data_file_slot(const TFileScanSlotInfo& slot_info, |
75 | | const std::string& column_name); |
76 | | static Status TEST_rewrite_slot_refs_to_global_index( |
77 | | VExprSPtr* expr, |
78 | | const std::unordered_map<int32_t, format::GlobalIndex>& slot_id_to_global_index); |
79 | | static RealtimeCounterDeltas TEST_collect_realtime_counter_deltas( |
80 | | const io::FileReaderStats& file_reader_stats, |
81 | | const io::FileCacheStatistics& file_cache_statistics, |
82 | | UncachedReaderBytesStorage uncached_reader_bytes_storage, int64_t* last_read_bytes, |
83 | | int64_t* last_read_rows, int64_t* last_bytes_read_from_local, |
84 | | int64_t* last_bytes_read_from_remote); |
85 | | #endif |
86 | | |
87 | | FileScannerV2(RuntimeState* state, FileScanLocalState* parent, int64_t limit, |
88 | | std::shared_ptr<SplitSourceConnector> split_source, RuntimeProfile* profile, |
89 | | ShardedKVCache* kv_cache, |
90 | | const std::unordered_map<std::string, int>* colname_to_slot_id); |
91 | | |
92 | | Status init(RuntimeState* state, const VExprContextSPtrs& conjuncts) override; |
93 | | Status _open_impl(RuntimeState* state) override; |
94 | | Status close(RuntimeState* state) override; |
95 | | void try_stop() override; |
96 | 0 | std::string get_name() override { return FileScannerV2::NAME; } |
97 | 0 | std::string get_current_scan_range_name() override { return _current_range_path; } |
98 | | void update_realtime_counters() override; |
99 | | |
100 | | protected: |
101 | | Status _get_block_impl(RuntimeState* state, Block* block, bool* eof) override; |
102 | | void _collect_profile_before_close() override; |
103 | | bool _should_update_load_counters() const override; |
104 | | |
105 | | private: |
106 | | static Status _validate_scan_range(const TFileScanRangeParams& params, |
107 | | const TFileRangeDesc& range); |
108 | | Status _get_next_scan_range(bool* has_next); |
109 | | TFileFormatType::type _get_current_format_type() const; |
110 | | Status _init_io_ctx(); |
111 | | Status _init_expr_ctxes(); |
112 | | Status _prepare_next_split(bool* eos); |
113 | | Status _init_table_reader(const TFileRangeDesc& range); |
114 | | Status _create_table_reader_for_format(const TFileRangeDesc& range, |
115 | | std::unique_ptr<format::TableReader>* reader) const; |
116 | | Status _prepare_table_reader_split(const TFileRangeDesc& range); |
117 | | bool _should_enable_file_meta_cache() const; |
118 | | std::optional<format::GlobalRowIdContext> _create_global_rowid_context( |
119 | | const TFileRangeDesc& range) const; |
120 | | Status _generate_partition_values(const TFileRangeDesc& range, |
121 | | std::map<std::string, Field>* partition_values) const; |
122 | | Status _parse_partition_value(const SlotDescriptor* slot_desc, const std::string& value, |
123 | | bool is_null, Field* field) const; |
124 | | Status _build_projected_columns(const format::TableReader& table_reader); |
125 | | Status _build_default_expr(const TFileScanSlotInfo& slot_info, VExprContextSPtr* ctx) const; |
126 | | static format::ColumnDefinition _build_table_column(const SlotDescriptor* slot_desc); |
127 | | Status _build_table_conjuncts(VExprContextSPtrs* conjuncts) const; |
128 | | static Status _to_file_format(TFileFormatType::type format_type, |
129 | | format::FileFormat* file_format); |
130 | | void _reset_adaptive_batch_size_state(); |
131 | | void _init_adaptive_batch_size_state(TFileFormatType::type format_type); |
132 | | bool _should_enable_adaptive_batch_size(TFileFormatType::type format_type) const; |
133 | | bool _should_run_adaptive_batch_size() const; |
134 | | size_t _predict_reader_batch_rows(); |
135 | | void _update_adaptive_batch_size(const Block& block); |
136 | | static RealtimeCounterDeltas _collect_realtime_counter_deltas( |
137 | | const io::FileReaderStats& file_reader_stats, |
138 | | const io::FileCacheStatistics& file_cache_statistics, |
139 | | UncachedReaderBytesStorage uncached_reader_bytes_storage, int64_t* last_read_bytes, |
140 | | int64_t* last_read_rows, int64_t* last_bytes_read_from_local, |
141 | | int64_t* last_bytes_read_from_remote); |
142 | | static UncachedReaderBytesStorage _uncached_reader_bytes_storage(TFileType::type file_type); |
143 | | void _report_file_reader_predicate_filtered_rows(); |
144 | | void _report_condition_cache_profile(); |
145 | | |
146 | | struct PartitionSlotInfo { |
147 | | const SlotDescriptor* slot_desc = nullptr; |
148 | | std::string canonical_name; |
149 | | }; |
150 | | |
151 | | const TFileScanRangeParams* _params = nullptr; |
152 | | std::shared_ptr<SplitSourceConnector> _split_source; |
153 | | bool _first_scan_range = false; |
154 | | bool _has_prepared_split = false; |
155 | | TFileRangeDesc _current_range; |
156 | | std::string _current_range_path; |
157 | | |
158 | | std::unique_ptr<format::TableReader> _table_reader; |
159 | | std::vector<format::ColumnDefinition> _projected_columns; |
160 | | // File formats without embedded schema, such as CSV, still need the FE slot descriptors in |
161 | | // file-column order. This mirrors old FileScanner::_file_slot_descs and is passed only to |
162 | | // readers that cannot derive their schema from file metadata. |
163 | | std::vector<SlotDescriptor*> _file_slot_descs; |
164 | | bool _need_global_rowid_column = false; |
165 | | std::unordered_map<int32_t, const SlotDescriptor*> _slot_id_to_desc; |
166 | | std::unordered_map<int32_t, format::GlobalIndex> _slot_id_to_global_index; |
167 | | std::unordered_map<std::string, PartitionSlotInfo> _partition_slot_descs; |
168 | | |
169 | | std::unique_ptr<io::FileCacheStatistics> _file_cache_statistics; |
170 | | std::unique_ptr<io::FileReaderStats> _file_reader_stats; |
171 | | std::shared_ptr<io::IOContext> _io_ctx; |
172 | | ShardedKVCache* _kv_cache = nullptr; |
173 | | |
174 | | RuntimeProfile::Counter* _get_block_timer = nullptr; |
175 | | RuntimeProfile::Counter* _file_counter = nullptr; |
176 | | RuntimeProfile::Counter* _file_read_bytes_counter = nullptr; |
177 | | RuntimeProfile::Counter* _file_read_calls_counter = nullptr; |
178 | | RuntimeProfile::Counter* _file_read_time_counter = nullptr; |
179 | | RuntimeProfile::Counter* _adaptive_batch_predicted_rows_counter = nullptr; |
180 | | RuntimeProfile::Counter* _adaptive_batch_actual_bytes_counter = nullptr; |
181 | | RuntimeProfile::Counter* _adaptive_batch_probe_count_counter = nullptr; |
182 | | std::unique_ptr<AdaptiveBlockSizePredictor> _block_size_predictor; |
183 | | int64_t _reported_predicate_filtered_rows = 0; |
184 | | int64_t _reported_condition_cache_hit_count = 0; |
185 | | int64_t _reported_condition_cache_filtered_rows = 0; |
186 | | int64_t _last_read_bytes = 0; |
187 | | int64_t _last_read_rows = 0; |
188 | | int64_t _last_bytes_read_from_local = 0; |
189 | | int64_t _last_bytes_read_from_remote = 0; |
190 | | }; |
191 | | |
192 | | } // namespace doris |