// 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. #ifndef DORIS_BE_SRC_QUERY_EXEC_OLAP_SCAN_NODE_H #define DORIS_BE_SRC_QUERY_EXEC_OLAP_SCAN_NODE_H #include #include #include #include #include #include #include #include #include "exec/olap_common.h" #include "exec/olap_meta_reader.h" #include "exec/olap_scanner.h" #include "exec/scan_node.h" #include "runtime/descriptors.h" #include "runtime/row_batch_interface.hpp" #include "runtime/vectorized_row_batch.h" #include "util/progress_updater.h" namespace doris { enum TransferStatus { READ_ROWBATCH = 1, INIT_HEAP = 2, BUILD_ROWBATCH = 3, MERGE = 4, FININSH = 5, ADD_ROWBATCH = 6, ERROR = 7 }; class OlapScanNode : public ScanNode { public: OlapScanNode(ObjectPool* pool, const TPlanNode& tnode, const DescriptorTbl& descs); ~OlapScanNode(); virtual Status init(const TPlanNode& tnode, RuntimeState* state = nullptr); virtual Status prepare(RuntimeState* state); virtual Status open(RuntimeState* state); virtual Status get_next(RuntimeState* state, RowBatch* row_batch, bool* eos); virtual Status close(RuntimeState* state); virtual Status set_scan_ranges(const std::vector& scan_ranges); protected: typedef struct { Tuple* tuple; int id; } HeapType; class IsFixedValueRangeVisitor : public boost::static_visitor { public: template bool operator()(T& v) const { return v.is_fixed_value_range(); } }; class GetFixedValueSizeVisitor : public boost::static_visitor { public: template size_t operator()(T& v) const { return v.get_fixed_value_size(); } }; class ExtendScanKeyVisitor : public boost::static_visitor { public: ExtendScanKeyVisitor(OlapScanKeys& scan_keys) : _scan_keys(scan_keys) { } template Status operator()(T& v) { return _scan_keys.extend_scan_key(v); } private: OlapScanKeys& _scan_keys; }; typedef boost::variant> string_list; class ToOlapFilterVisitor : public boost::static_visitor { public: template std::string operator()(T& v, P& v2) const { return v.to_olap_filter(v2); } }; class MergeComparison { public: MergeComparison(CompareLargeFunc compute_fn, int offset) { _compute_fn = compute_fn; _offset = offset; } bool operator()(const HeapType& lhs, const HeapType& rhs) const { return (*_compute_fn)(lhs.tuple->get_slot(_offset), rhs.tuple->get_slot(_offset)); } private: CompareLargeFunc _compute_fn; int _offset; }; typedef std::priority_queue, MergeComparison> Heap; void display_heap(Heap& heap) { Heap h = heap; std::stringstream s; s << "Heap: ["; while (!h.empty()) { HeapType v = h.top(); s << "\nID: " << v.id << " Value:" << Tuple::to_string(v.tuple, *_tuple_desc); h.pop(); } VLOG(1) << s.str() << "\n]"; } Status start_scan(RuntimeState* state); Status normalize_conjuncts(); Status build_olap_filters(); Status select_scan_ranges(); Status build_scan_key(); Status split_scan_range(); Status start_scan_thread(RuntimeState* state); template Status normalize_predicate(ColumnValueRange& range, SlotDescriptor* slot); template Status normalize_in_predicate(SlotDescriptor* slot, ColumnValueRange* range); template Status normalize_binary_predicate(SlotDescriptor* slot, ColumnValueRange* range); bool select_scan_range(boost::shared_ptr scan_range); Status get_sub_scan_range( boost::shared_ptr scan_range, std::vector* sub_range); void transfer_thread(RuntimeState* state); //void vectorized_scanner_thread(OlapScanner* scanner); void scanner_thread(OlapScanner* scanner); Status add_one_batch(RowBatchInterface* row_batch); // Write debug string of this into out. virtual void debug_string(int indentation_level, std::stringstream* out) const; private: void _init_counter(RuntimeState* state); void construct_is_null_pred_in_where_pred(Expr* expr, SlotDescriptor* slot, std::string is_null_str); friend class OlapScanner; std::vector _is_null_vector; // Tuple id resolved in prepare() to set _tuple_desc; TupleId _tuple_id; // doris scan node used to scan doris TOlapScanNode _olap_scan_node; // tuple descriptors const TupleDescriptor* _tuple_desc; // tuple index int _tuple_idx; // string slots std::vector _string_slots; bool _eos; // column -> ColumnValueRange map std::map _column_value_ranges; OlapScanKeys _scan_keys; std::list > _doris_scan_ranges; std::vector > _query_scan_ranges; std::vector _query_key_ranges; std::vector _olap_filter; // Order Result Flag bool _is_result_order; // Pool for storing allocated scanner objects. We don't want to use the // runtime pool to ensure that the scanner objects are deleted before this // object is. boost::scoped_ptr _scanner_pool; // Thread group for transfer thread boost::thread_group _transfer_thread; // Keeps track of total splits and the number finished. ProgressUpdater _progress; // Lock and condition variables protecting _materialized_row_batches. Row batches are // produced asynchronously by the scanner threads and consumed by the main thread in // GetNext. Row batches must be processed by the main thread in the order they are // queued to avoid freeing attached resources prematurely (row batches will never depend // on resources attached to earlier batches in the queue). // This lock cannot be taken together with any other locks except _lock. boost::mutex _row_batches_lock; boost::condition_variable _row_batch_added_cv; boost::condition_variable _row_batch_consumed_cv; std::list _materialized_row_batches; boost::mutex _scan_batches_lock; boost::condition_variable _scan_batch_added_cv; int32_t _scanner_task_finish_count; std::list _scan_row_batches; std::list _all_olap_scanners; std::list _olap_scanners; int _max_materialized_row_batches; bool _start; bool _scanner_done; bool _transfer_done; size_t _direct_conjunct_size; boost::posix_time::time_duration _wait_duration; int _total_assign_num; int _nice; // protect _status, for many thread may change _status boost::mutex _status_mutex; Status _status; RuntimeState* _runtime_state; RuntimeProfile::Counter* _scan_timer; RuntimeProfile::Counter* _tablet_counter; RuntimeProfile::Counter* _rows_pushed_cond_filtered_counter = nullptr; TResourceInfo* _resource_info; int64_t _buffered_bytes; int64_t _running_thread; EvalConjunctsFn _eval_conjuncts_fn; // Counters RuntimeProfile::Counter* _io_timer = nullptr; RuntimeProfile::Counter* _read_compressed_counter = nullptr; RuntimeProfile::Counter* _decompressor_timer = nullptr; RuntimeProfile::Counter* _read_uncompressed_counter = nullptr; RuntimeProfile::Counter* _raw_rows_counter = nullptr; RuntimeProfile::Counter* _rows_vec_cond_counter = nullptr; RuntimeProfile::Counter* _vec_cond_timer = nullptr; RuntimeProfile::Counter* _stats_filtered_counter = nullptr; RuntimeProfile::Counter* _del_filtered_counter = nullptr; RuntimeProfile::Counter* _block_load_timer = nullptr; RuntimeProfile::Counter* _block_load_counter = nullptr; RuntimeProfile::Counter* _block_fetch_timer = nullptr; RuntimeProfile::Counter* _index_load_timer = nullptr; }; } // namespace doris #endif