Coverage Report

Created: 2026-08-28 01:04

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
be/src/exec/scan/parallel_scanner_builder.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 <memory>
21
#include <string>
22
#include <unordered_map>
23
#include <utility>
24
25
#include "exec/scan/olap_scanner.h"
26
#include "io/io_common.h"
27
#include "storage/rowset/rowset_fwd.h"
28
#include "storage/segment/row_ranges.h"
29
#include "storage/segment/segment_loader.h"
30
#include "storage/tablet/base_tablet.h"
31
#include "storage/tablet/tablet.h"
32
33
namespace doris {
34
35
class OlapScanLocalState;
36
37
class Scanner;
38
39
using ScannerSPtr = std::shared_ptr<Scanner>;
40
41
class ParallelScannerBuilder {
42
public:
43
    ParallelScannerBuilder(OlapScanLocalState* parent,
44
                           const std::vector<TabletWithVersion>& tablets,
45
                           std::vector<TabletReadSource>& read_sources,
46
                           const std::vector<std::unique_ptr<TPaloScanRange>>& scan_ranges,
47
                           const std::shared_ptr<RuntimeProfile>& profile,
48
                           const std::vector<OlapScanRange*>& key_ranges, RuntimeState* state,
49
                           int64_t limit, bool is_dup_mow_key, bool is_preaggregation)
50
2
            : _parent(parent),
51
2
              _scanner_profile(profile),
52
2
              _state(state),
53
2
              _limit(limit),
54
2
              _is_dup_mow_key(is_dup_mow_key),
55
2
              _is_preaggregation(is_preaggregation),
56
2
              _tablets(tablets.cbegin(), tablets.cend()),
57
2
              _key_ranges(key_ranges.cbegin(), key_ranges.cend()),
58
2
              _scan_ranges(scan_ranges),
59
2
              _read_sources(read_sources) {
60
2
        DORIS_CHECK_EQ(_tablets.size(), scan_ranges.size());
61
20.0k
        for (size_t i = 0; i < _tablets.size(); ++i) {
62
20.0k
            DORIS_CHECK(scan_ranges[i] != nullptr);
63
20.0k
            DORIS_CHECK_EQ(_tablets[i].tablet->tablet_id(), scan_ranges[i]->tablet_id);
64
20.0k
        }
65
2
    }
66
67
    Status build_scanners(std::list<ScannerSPtr>& scanners);
68
69
0
    void set_max_scanners_count(size_t count) { _max_scanners_count = count; }
70
71
0
    void set_min_rows_per_scanner(int64_t size) { _min_rows_per_scanner = size; }
72
73
0
    void set_scan_parallelism_by_per_segment(bool v) { _scan_parallelism_by_per_segment = v; }
74
75
0
    const OlapReaderStatistics* builder_stats() const { return &_builder_stats; }
76
77
private:
78
    Status _load();
79
80
    Status _build_scanners_by_rowid(std::list<ScannerSPtr>& scanners);
81
82
    // Build scanners so that each segment is handled by its own scanner.
83
    Status _build_scanners_by_per_segment(std::list<ScannerSPtr>& scanners);
84
85
    std::shared_ptr<OlapScanner> _build_scanner(BaseTabletSPtr tablet, int64_t version,
86
                                                const std::vector<OlapScanRange*>& key_ranges,
87
                                                const TPaloScanRange& scan_range,
88
                                                TabletReadSource&& read_source,
89
                                                io::FileCacheStatistics&& initial_file_cache_stats);
90
91
    OlapScanLocalState* _parent;
92
93
    /// Max scanners count limit to build
94
    size_t _max_scanners_count {16};
95
96
    /// Min rows per scanner
97
    size_t _min_rows_per_scanner {2 * 1024 * 1024};
98
99
    size_t _total_rows {};
100
101
    size_t _rows_per_scanner {_min_rows_per_scanner};
102
103
    std::map<RowsetId, std::vector<size_t>> _all_segments_rows;
104
    std::unordered_map<int64_t, io::FileCacheStatistics> _tablet_preload_file_cache_stats;
105
106
    // Force building one scanner per segment when true.
107
    bool _scan_parallelism_by_per_segment {false};
108
109
    std::shared_ptr<RuntimeProfile> _scanner_profile;
110
    OlapReaderStatistics _builder_stats;
111
    RuntimeState* _state;
112
    int64_t _limit;
113
    bool _is_dup_mow_key;
114
    // The flag of preagg's meaning is whether return pre agg data(or partial agg data)
115
    // PreAgg ON: The storage layer returns partially aggregated data without additional processing. (Fast data reading)
116
    // for example, if a table is select userid,count(*) from base table.
117
    // And the user send a query like select userid,count(*) from base table group by userid.
118
    // then the storage layer do not need do aggregation, it could just return the partial agg data, because the compute layer will do aggregation.
119
    // PreAgg OFF: The storage layer must complete pre-aggregation and return fully aggregated data. (Slow data reading)
120
    bool _is_preaggregation;
121
    std::vector<TabletWithVersion> _tablets;
122
    std::vector<OlapScanRange*> _key_ranges;
123
    const std::vector<std::unique_ptr<TPaloScanRange>>& _scan_ranges;
124
    std::unordered_map<int64_t, TabletReadSource> _all_read_sources;
125
    std::vector<TabletReadSource>& _read_sources;
126
};
127
128
} // namespace doris