Coverage Report

Created: 2026-10-09 15:53

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
be/src/storage/segment/rle_page.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 "common/cast_set.h"
21
#include "storage/field_type.h"           // for FieldType
22
#include "storage/segment/options.h"      // for PageBuilderOptions/PageDecoderOptions
23
#include "storage/segment/page_builder.h" // for PageBuilder
24
#include "storage/segment/page_decoder.h" // for PageDecoder
25
#include "storage/types.h"                // for TypeTraits
26
#include "util/coding.h"                  // for encode_fixed32_le/decode_fixed32_le
27
#include "util/rle_encoding.h"            // for RleEncoder/RleDecoder
28
#include "util/slice.h"                   // for OwnedSlice
29
30
namespace doris {
31
namespace segment_v2 {
32
33
enum { RLE_PAGE_HEADER_SIZE = 4 };
34
35
// RLE builder for generic integer and bool types. What is missing is some way
36
// to enforce that this can only be instantiated for INT and BOOL types.
37
//
38
// The page format is as follows:
39
//
40
// 1. Header: (4 bytes total)
41
//
42
//    <num_elements> [32-bit]
43
//      The number of elements encoded in the page.
44
//
45
//    NOTE: all on-disk ints are encoded little-endian
46
//
47
// 2. Element data
48
//
49
//    The header is followed by the rle-encoded element data.
50
//
51
// This Rle encoding algorithm is only effective for repeated INT type and bool type,
52
// It is not good for sequence number or random number. BitshufflePage is recommended
53
// for these case.
54
//
55
// TODO(hkp): optimize rle algorithm
56
template <FieldType Type>
57
class RlePageBuilder : public PageBuilderHelper<RlePageBuilder<Type> > {
58
public:
59
    using Self = RlePageBuilder<Type>;
60
    friend class PageBuilderHelper<Self>;
61
62
205
    Status init() override {
63
205
        switch (Type) {
64
201
        case FieldType::OLAP_FIELD_TYPE_BOOL: {
65
201
            _bit_width = 1;
66
201
            break;
67
0
        }
68
4
        default: {
69
4
            _bit_width = SIZE_OF_TYPE * 8;
70
4
            break;
71
0
        }
72
205
        }
73
205
        _rle_encoder = new RleEncoder<CppType>(&_buf, _bit_width);
74
205
        return reset();
75
205
    }
_ZN5doris10segment_v214RlePageBuilderILNS_9FieldTypeE5EE4initEv
Line
Count
Source
62
4
    Status init() override {
63
4
        switch (Type) {
64
0
        case FieldType::OLAP_FIELD_TYPE_BOOL: {
65
0
            _bit_width = 1;
66
0
            break;
67
0
        }
68
4
        default: {
69
4
            _bit_width = SIZE_OF_TYPE * 8;
70
4
            break;
71
0
        }
72
4
        }
73
4
        _rle_encoder = new RleEncoder<CppType>(&_buf, _bit_width);
74
4
        return reset();
75
4
    }
_ZN5doris10segment_v214RlePageBuilderILNS_9FieldTypeE24EE4initEv
Line
Count
Source
62
201
    Status init() override {
63
201
        switch (Type) {
64
201
        case FieldType::OLAP_FIELD_TYPE_BOOL: {
65
201
            _bit_width = 1;
66
201
            break;
67
0
        }
68
0
        default: {
69
0
            _bit_width = SIZE_OF_TYPE * 8;
70
0
            break;
71
0
        }
72
201
        }
73
201
        _rle_encoder = new RleEncoder<CppType>(&_buf, _bit_width);
74
201
        return reset();
75
201
    }
76
77
205
    ~RlePageBuilder() { delete _rle_encoder; }
_ZN5doris10segment_v214RlePageBuilderILNS_9FieldTypeE5EED2Ev
Line
Count
Source
77
4
    ~RlePageBuilder() { delete _rle_encoder; }
_ZN5doris10segment_v214RlePageBuilderILNS_9FieldTypeE24EED2Ev
Line
Count
Source
77
201
    ~RlePageBuilder() { delete _rle_encoder; }
78
79
392
    bool is_page_full() override { return _rle_encoder->len() >= _options.data_page_size; }
Unexecuted instantiation: _ZN5doris10segment_v214RlePageBuilderILNS_9FieldTypeE5EE12is_page_fullEv
_ZN5doris10segment_v214RlePageBuilderILNS_9FieldTypeE24EE12is_page_fullEv
Line
Count
Source
79
392
    bool is_page_full() override { return _rle_encoder->len() >= _options.data_page_size; }
80
81
398
    Status add(const uint8_t* vals, size_t* count) override {
82
398
        DCHECK(!_finished);
83
398
        auto new_vals = reinterpret_cast<const CppType*>(vals);
84
43.5k
        for (int i = 0; i < *count; ++i) {
85
            // note: vals is not guaranteed to be aligned for now, thus memcpy here
86
43.1k
            CppType value;
87
43.1k
            memcpy(&value, &new_vals[i], SIZE_OF_TYPE);
88
43.1k
            _rle_encoder->Put(value);
89
43.1k
        }
90
91
398
        _count += *count;
92
398
        _raw_data_size += *count * SIZE_OF_TYPE;
93
398
        return Status::OK();
94
398
    }
_ZN5doris10segment_v214RlePageBuilderILNS_9FieldTypeE5EE3addEPKhPm
Line
Count
Source
81
4
    Status add(const uint8_t* vals, size_t* count) override {
82
4
        DCHECK(!_finished);
83
4
        auto new_vals = reinterpret_cast<const CppType*>(vals);
84
30.1k
        for (int i = 0; i < *count; ++i) {
85
            // note: vals is not guaranteed to be aligned for now, thus memcpy here
86
30.1k
            CppType value;
87
30.1k
            memcpy(&value, &new_vals[i], SIZE_OF_TYPE);
88
30.1k
            _rle_encoder->Put(value);
89
30.1k
        }
90
91
4
        _count += *count;
92
4
        _raw_data_size += *count * SIZE_OF_TYPE;
93
4
        return Status::OK();
94
4
    }
_ZN5doris10segment_v214RlePageBuilderILNS_9FieldTypeE24EE3addEPKhPm
Line
Count
Source
81
394
    Status add(const uint8_t* vals, size_t* count) override {
82
394
        DCHECK(!_finished);
83
394
        auto new_vals = reinterpret_cast<const CppType*>(vals);
84
13.4k
        for (int i = 0; i < *count; ++i) {
85
            // note: vals is not guaranteed to be aligned for now, thus memcpy here
86
13.0k
            CppType value;
87
13.0k
            memcpy(&value, &new_vals[i], SIZE_OF_TYPE);
88
13.0k
            _rle_encoder->Put(value);
89
13.0k
        }
90
91
394
        _count += *count;
92
394
        _raw_data_size += *count * SIZE_OF_TYPE;
93
394
        return Status::OK();
94
394
    }
95
96
214
    Status finish(OwnedSlice* slice) override {
97
214
        DCHECK(!_finished);
98
214
        _finished = true;
99
        // here should Flush first and then encode the count header
100
        // or it will lead to a bug if the header is less than 8 byte and the data is small
101
214
        _rle_encoder->Flush();
102
214
        encode_fixed32_le(&_buf[0], cast_set<uint32_t>(_count));
103
214
        *slice = _buf.build();
104
214
        return Status::OK();
105
214
    }
_ZN5doris10segment_v214RlePageBuilderILNS_9FieldTypeE5EE6finishEPNS_10OwnedSliceE
Line
Count
Source
96
4
    Status finish(OwnedSlice* slice) override {
97
4
        DCHECK(!_finished);
98
4
        _finished = true;
99
        // here should Flush first and then encode the count header
100
        // or it will lead to a bug if the header is less than 8 byte and the data is small
101
4
        _rle_encoder->Flush();
102
4
        encode_fixed32_le(&_buf[0], cast_set<uint32_t>(_count));
103
4
        *slice = _buf.build();
104
4
        return Status::OK();
105
4
    }
_ZN5doris10segment_v214RlePageBuilderILNS_9FieldTypeE24EE6finishEPNS_10OwnedSliceE
Line
Count
Source
96
210
    Status finish(OwnedSlice* slice) override {
97
210
        DCHECK(!_finished);
98
210
        _finished = true;
99
        // here should Flush first and then encode the count header
100
        // or it will lead to a bug if the header is less than 8 byte and the data is small
101
210
        _rle_encoder->Flush();
102
210
        encode_fixed32_le(&_buf[0], cast_set<uint32_t>(_count));
103
210
        *slice = _buf.build();
104
210
        return Status::OK();
105
210
    }
106
107
413
    Status reset() override {
108
413
        RETURN_IF_CATCH_EXCEPTION({
109
413
            _count = 0;
110
413
            _finished = false;
111
413
            _raw_data_size = 0;
112
413
            _rle_encoder->Clear();
113
413
            _rle_encoder->Reserve(RLE_PAGE_HEADER_SIZE, 0);
114
413
        });
115
413
        return Status::OK();
116
413
    }
_ZN5doris10segment_v214RlePageBuilderILNS_9FieldTypeE5EE5resetEv
Line
Count
Source
107
4
    Status reset() override {
108
4
        RETURN_IF_CATCH_EXCEPTION({
109
4
            _count = 0;
110
4
            _finished = false;
111
4
            _raw_data_size = 0;
112
4
            _rle_encoder->Clear();
113
4
            _rle_encoder->Reserve(RLE_PAGE_HEADER_SIZE, 0);
114
4
        });
115
4
        return Status::OK();
116
4
    }
_ZN5doris10segment_v214RlePageBuilderILNS_9FieldTypeE24EE5resetEv
Line
Count
Source
107
409
    Status reset() override {
108
409
        RETURN_IF_CATCH_EXCEPTION({
109
409
            _count = 0;
110
409
            _finished = false;
111
409
            _raw_data_size = 0;
112
409
            _rle_encoder->Clear();
113
409
            _rle_encoder->Reserve(RLE_PAGE_HEADER_SIZE, 0);
114
409
        });
115
409
        return Status::OK();
116
409
    }
117
118
4
    size_t count() const override { return _count; }
_ZNK5doris10segment_v214RlePageBuilderILNS_9FieldTypeE5EE5countEv
Line
Count
Source
118
3
    size_t count() const override { return _count; }
_ZNK5doris10segment_v214RlePageBuilderILNS_9FieldTypeE24EE5countEv
Line
Count
Source
118
1
    size_t count() const override { return _count; }
119
120
104
    uint64_t size() const override { return _rle_encoder->len(); }
Unexecuted instantiation: _ZNK5doris10segment_v214RlePageBuilderILNS_9FieldTypeE5EE4sizeEv
_ZNK5doris10segment_v214RlePageBuilderILNS_9FieldTypeE24EE4sizeEv
Line
Count
Source
120
104
    uint64_t size() const override { return _rle_encoder->len(); }
121
122
208
    uint64_t get_raw_data_size() const override { return _raw_data_size; }
Unexecuted instantiation: _ZNK5doris10segment_v214RlePageBuilderILNS_9FieldTypeE5EE17get_raw_data_sizeEv
_ZNK5doris10segment_v214RlePageBuilderILNS_9FieldTypeE24EE17get_raw_data_sizeEv
Line
Count
Source
122
208
    uint64_t get_raw_data_size() const override { return _raw_data_size; }
123
124
private:
125
    RlePageBuilder(const PageBuilderOptions& options)
126
205
            : _options(options),
127
205
              _count(0),
128
205
              _finished(false),
129
205
              _bit_width(0),
130
205
              _rle_encoder(nullptr) {}
_ZN5doris10segment_v214RlePageBuilderILNS_9FieldTypeE5EEC2ERKNS0_18PageBuilderOptionsE
Line
Count
Source
126
4
            : _options(options),
127
4
              _count(0),
128
4
              _finished(false),
129
4
              _bit_width(0),
130
4
              _rle_encoder(nullptr) {}
_ZN5doris10segment_v214RlePageBuilderILNS_9FieldTypeE24EEC2ERKNS0_18PageBuilderOptionsE
Line
Count
Source
126
201
            : _options(options),
127
201
              _count(0),
128
201
              _finished(false),
129
201
              _bit_width(0),
130
201
              _rle_encoder(nullptr) {}
131
132
    typedef typename TypeTraits<Type>::CppType CppType;
133
    enum { SIZE_OF_TYPE = TypeTraits<Type>::size };
134
135
    PageBuilderOptions _options;
136
    size_t _count;
137
    bool _finished;
138
    int _bit_width;
139
    RleEncoder<CppType>* _rle_encoder = nullptr;
140
    faststring _buf;
141
    uint64_t _raw_data_size = 0;
142
};
143
144
template <FieldType Type>
145
class RlePageDecoder : public PageDecoder {
146
public:
147
    RlePageDecoder(Slice slice, const PageDecoderOptions& options)
148
47
            : _data(slice),
149
47
              _options(options),
150
47
              _parsed(false),
151
47
              _num_elements(0),
152
47
              _cur_index(0),
153
47
              _bit_width(0) {}
_ZN5doris10segment_v214RlePageDecoderILNS_9FieldTypeE5EEC2ENS_5SliceERKNS0_18PageDecoderOptionsE
Line
Count
Source
148
3
            : _data(slice),
149
3
              _options(options),
150
3
              _parsed(false),
151
3
              _num_elements(0),
152
3
              _cur_index(0),
153
3
              _bit_width(0) {}
_ZN5doris10segment_v214RlePageDecoderILNS_9FieldTypeE24EEC2ENS_5SliceERKNS0_18PageDecoderOptionsE
Line
Count
Source
148
44
            : _data(slice),
149
44
              _options(options),
150
44
              _parsed(false),
151
44
              _num_elements(0),
152
44
              _cur_index(0),
153
44
              _bit_width(0) {}
154
155
47
    Status init() override {
156
47
        CHECK(!_parsed);
157
158
47
        if (_data.size < RLE_PAGE_HEADER_SIZE) {
159
0
            return Status::Corruption("not enough bytes for header in RleBitMapBlockDecoder");
160
0
        }
161
47
        _num_elements = decode_fixed32_le((const uint8_t*)&_data[0]);
162
163
47
        _parsed = true;
164
165
47
        switch (Type) {
166
44
        case FieldType::OLAP_FIELD_TYPE_BOOL: {
167
44
            _bit_width = 1;
168
44
            break;
169
0
        }
170
3
        default: {
171
3
            _bit_width = SIZE_OF_TYPE * 8;
172
3
            break;
173
0
        }
174
47
        }
175
176
47
        _rle_decoder =
177
47
                RleDecoder<CppType>((uint8_t*)_data.data + RLE_PAGE_HEADER_SIZE,
178
47
                                    cast_set<int>(_data.size - RLE_PAGE_HEADER_SIZE), _bit_width);
179
180
47
        RETURN_IF_ERROR(seek_to_position_in_page(0));
181
47
        return Status::OK();
182
47
    }
_ZN5doris10segment_v214RlePageDecoderILNS_9FieldTypeE5EE4initEv
Line
Count
Source
155
3
    Status init() override {
156
3
        CHECK(!_parsed);
157
158
3
        if (_data.size < RLE_PAGE_HEADER_SIZE) {
159
0
            return Status::Corruption("not enough bytes for header in RleBitMapBlockDecoder");
160
0
        }
161
3
        _num_elements = decode_fixed32_le((const uint8_t*)&_data[0]);
162
163
3
        _parsed = true;
164
165
3
        switch (Type) {
166
0
        case FieldType::OLAP_FIELD_TYPE_BOOL: {
167
0
            _bit_width = 1;
168
0
            break;
169
0
        }
170
3
        default: {
171
3
            _bit_width = SIZE_OF_TYPE * 8;
172
3
            break;
173
0
        }
174
3
        }
175
176
3
        _rle_decoder =
177
3
                RleDecoder<CppType>((uint8_t*)_data.data + RLE_PAGE_HEADER_SIZE,
178
3
                                    cast_set<int>(_data.size - RLE_PAGE_HEADER_SIZE), _bit_width);
179
180
3
        RETURN_IF_ERROR(seek_to_position_in_page(0));
181
3
        return Status::OK();
182
3
    }
_ZN5doris10segment_v214RlePageDecoderILNS_9FieldTypeE24EE4initEv
Line
Count
Source
155
44
    Status init() override {
156
44
        CHECK(!_parsed);
157
158
44
        if (_data.size < RLE_PAGE_HEADER_SIZE) {
159
0
            return Status::Corruption("not enough bytes for header in RleBitMapBlockDecoder");
160
0
        }
161
44
        _num_elements = decode_fixed32_le((const uint8_t*)&_data[0]);
162
163
44
        _parsed = true;
164
165
44
        switch (Type) {
166
44
        case FieldType::OLAP_FIELD_TYPE_BOOL: {
167
44
            _bit_width = 1;
168
44
            break;
169
0
        }
170
0
        default: {
171
0
            _bit_width = SIZE_OF_TYPE * 8;
172
0
            break;
173
0
        }
174
44
        }
175
176
44
        _rle_decoder =
177
44
                RleDecoder<CppType>((uint8_t*)_data.data + RLE_PAGE_HEADER_SIZE,
178
44
                                    cast_set<int>(_data.size - RLE_PAGE_HEADER_SIZE), _bit_width);
179
180
44
        RETURN_IF_ERROR(seek_to_position_in_page(0));
181
44
        return Status::OK();
182
44
    }
183
184
447
    Status seek_to_position_in_page(size_t pos) override {
185
447
        DCHECK(_parsed) << "Must call init()";
186
447
        DCHECK_LE(pos, _num_elements)
187
0
                << "Tried to seek to " << pos << " which is > number of elements (" << _num_elements
188
0
                << ") in the block!";
189
        // If the block is empty (e.g. the column is filled with nulls), there is no data to seek.
190
447
        if (_num_elements == 0) [[unlikely]] {
191
0
            if (pos != 0) {
192
0
                return Status::Error<ErrorCode::INTERNAL_ERROR, false>(
193
0
                        "seek pos {} is larger than total elements  {}", pos, _num_elements);
194
0
            } else {
195
0
                return Status::OK();
196
0
            }
197
0
        }
198
447
        if (_cur_index == pos) {
199
            // No need to seek.
200
47
            return Status::OK();
201
400
        } else if (_cur_index < pos) {
202
197
            size_t nskip = pos - _cur_index;
203
197
            _rle_decoder.Skip(nskip);
204
203
        } else {
205
203
            _rle_decoder = RleDecoder<CppType>((uint8_t*)_data.data + RLE_PAGE_HEADER_SIZE,
206
203
                                               cast_set<int>(_data.size - RLE_PAGE_HEADER_SIZE),
207
203
                                               _bit_width);
208
203
            _rle_decoder.Skip(pos);
209
203
        }
210
400
        _cur_index = pos;
211
400
        return Status::OK();
212
447
    }
_ZN5doris10segment_v214RlePageDecoderILNS_9FieldTypeE5EE24seek_to_position_in_pageEm
Line
Count
Source
184
303
    Status seek_to_position_in_page(size_t pos) override {
185
303
        DCHECK(_parsed) << "Must call init()";
186
303
        DCHECK_LE(pos, _num_elements)
187
0
                << "Tried to seek to " << pos << " which is > number of elements (" << _num_elements
188
0
                << ") in the block!";
189
        // If the block is empty (e.g. the column is filled with nulls), there is no data to seek.
190
303
        if (_num_elements == 0) [[unlikely]] {
191
0
            if (pos != 0) {
192
0
                return Status::Error<ErrorCode::INTERNAL_ERROR, false>(
193
0
                        "seek pos {} is larger than total elements  {}", pos, _num_elements);
194
0
            } else {
195
0
                return Status::OK();
196
0
            }
197
0
        }
198
303
        if (_cur_index == pos) {
199
            // No need to seek.
200
3
            return Status::OK();
201
300
        } else if (_cur_index < pos) {
202
149
            size_t nskip = pos - _cur_index;
203
149
            _rle_decoder.Skip(nskip);
204
151
        } else {
205
151
            _rle_decoder = RleDecoder<CppType>((uint8_t*)_data.data + RLE_PAGE_HEADER_SIZE,
206
151
                                               cast_set<int>(_data.size - RLE_PAGE_HEADER_SIZE),
207
151
                                               _bit_width);
208
151
            _rle_decoder.Skip(pos);
209
151
        }
210
300
        _cur_index = pos;
211
300
        return Status::OK();
212
303
    }
_ZN5doris10segment_v214RlePageDecoderILNS_9FieldTypeE24EE24seek_to_position_in_pageEm
Line
Count
Source
184
144
    Status seek_to_position_in_page(size_t pos) override {
185
144
        DCHECK(_parsed) << "Must call init()";
186
144
        DCHECK_LE(pos, _num_elements)
187
0
                << "Tried to seek to " << pos << " which is > number of elements (" << _num_elements
188
0
                << ") in the block!";
189
        // If the block is empty (e.g. the column is filled with nulls), there is no data to seek.
190
144
        if (_num_elements == 0) [[unlikely]] {
191
0
            if (pos != 0) {
192
0
                return Status::Error<ErrorCode::INTERNAL_ERROR, false>(
193
0
                        "seek pos {} is larger than total elements  {}", pos, _num_elements);
194
0
            } else {
195
0
                return Status::OK();
196
0
            }
197
0
        }
198
144
        if (_cur_index == pos) {
199
            // No need to seek.
200
44
            return Status::OK();
201
100
        } else if (_cur_index < pos) {
202
48
            size_t nskip = pos - _cur_index;
203
48
            _rle_decoder.Skip(nskip);
204
52
        } else {
205
52
            _rle_decoder = RleDecoder<CppType>((uint8_t*)_data.data + RLE_PAGE_HEADER_SIZE,
206
52
                                               cast_set<int>(_data.size - RLE_PAGE_HEADER_SIZE),
207
52
                                               _bit_width);
208
52
            _rle_decoder.Skip(pos);
209
52
        }
210
100
        _cur_index = pos;
211
100
        return Status::OK();
212
144
    }
213
214
531
    Status next_batch(size_t* n, MutableColumnPtr& dst) override {
215
531
        DCHECK(_parsed);
216
531
        if (*n == 0 || _cur_index >= _num_elements) [[unlikely]] {
217
0
            *n = 0;
218
0
            return Status::OK();
219
0
        }
220
221
531
        size_t to_fetch = std::min(*n, static_cast<size_t>(_num_elements - _cur_index));
222
531
        size_t remaining = to_fetch;
223
531
        bool result = false;
224
531
        CppType value;
225
42.4k
        while (remaining > 0) {
226
41.9k
            result = _rle_decoder.Get(&value);
227
41.9k
            DCHECK(result);
228
41.9k
            dst->insert_data((char*)(&value), SIZE_OF_TYPE);
229
41.9k
            remaining--;
230
41.9k
        }
231
232
531
        _cur_index += to_fetch;
233
531
        *n = to_fetch;
234
531
        return Status::OK();
235
531
    }
_ZN5doris10segment_v214RlePageDecoderILNS_9FieldTypeE5EE10next_batchEPmRNS_3COWINS_7IColumnEE11mutable_ptrIS6_EE
Line
Count
Source
214
303
    Status next_batch(size_t* n, MutableColumnPtr& dst) override {
215
303
        DCHECK(_parsed);
216
303
        if (*n == 0 || _cur_index >= _num_elements) [[unlikely]] {
217
0
            *n = 0;
218
0
            return Status::OK();
219
0
        }
220
221
303
        size_t to_fetch = std::min(*n, static_cast<size_t>(_num_elements - _cur_index));
222
303
        size_t remaining = to_fetch;
223
303
        bool result = false;
224
303
        CppType value;
225
30.6k
        while (remaining > 0) {
226
30.3k
            result = _rle_decoder.Get(&value);
227
30.3k
            DCHECK(result);
228
30.3k
            dst->insert_data((char*)(&value), SIZE_OF_TYPE);
229
30.3k
            remaining--;
230
30.3k
        }
231
232
303
        _cur_index += to_fetch;
233
303
        *n = to_fetch;
234
303
        return Status::OK();
235
303
    }
_ZN5doris10segment_v214RlePageDecoderILNS_9FieldTypeE24EE10next_batchEPmRNS_3COWINS_7IColumnEE11mutable_ptrIS6_EE
Line
Count
Source
214
228
    Status next_batch(size_t* n, MutableColumnPtr& dst) override {
215
228
        DCHECK(_parsed);
216
228
        if (*n == 0 || _cur_index >= _num_elements) [[unlikely]] {
217
0
            *n = 0;
218
0
            return Status::OK();
219
0
        }
220
221
228
        size_t to_fetch = std::min(*n, static_cast<size_t>(_num_elements - _cur_index));
222
228
        size_t remaining = to_fetch;
223
228
        bool result = false;
224
228
        CppType value;
225
11.8k
        while (remaining > 0) {
226
11.6k
            result = _rle_decoder.Get(&value);
227
11.6k
            DCHECK(result);
228
11.6k
            dst->insert_data((char*)(&value), SIZE_OF_TYPE);
229
11.6k
            remaining--;
230
11.6k
        }
231
232
228
        _cur_index += to_fetch;
233
228
        *n = to_fetch;
234
228
        return Status::OK();
235
228
    }
236
237
    Status read_by_rowids(const rowid_t* rowids, ordinal_t page_first_ordinal, size_t* n,
238
2
                          MutableColumnPtr& dst) override {
239
2
        DCHECK(_parsed);
240
2
        if (*n == 0 || _cur_index >= _num_elements) [[unlikely]] {
241
0
            *n = 0;
242
0
            return Status::OK();
243
0
        }
244
245
2
        auto total = *n;
246
2
        bool result = false;
247
2
        size_t read_count = 0;
248
2
        CppType value;
249
6
        for (size_t i = 0; i < total; ++i) {
250
4
            ordinal_t ord = rowids[i] - page_first_ordinal;
251
4
            if (UNLIKELY(ord >= _num_elements)) {
252
0
                *n = read_count;
253
0
                return Status::OK();
254
0
            }
255
256
4
            _rle_decoder.Skip(ord - _cur_index);
257
4
            _cur_index = ord;
258
259
4
            result = _rle_decoder.Get(&value);
260
4
            _cur_index++;
261
4
            DCHECK(result);
262
4
            dst->insert_data((char*)(&value), SIZE_OF_TYPE);
263
4
            read_count++;
264
4
        }
265
2
        *n = read_count;
266
2
        return Status::OK();
267
2
    }
Unexecuted instantiation: _ZN5doris10segment_v214RlePageDecoderILNS_9FieldTypeE5EE14read_by_rowidsEPKjmPmRNS_3COWINS_7IColumnEE11mutable_ptrIS8_EE
_ZN5doris10segment_v214RlePageDecoderILNS_9FieldTypeE24EE14read_by_rowidsEPKjmPmRNS_3COWINS_7IColumnEE11mutable_ptrIS8_EE
Line
Count
Source
238
2
                          MutableColumnPtr& dst) override {
239
2
        DCHECK(_parsed);
240
2
        if (*n == 0 || _cur_index >= _num_elements) [[unlikely]] {
241
0
            *n = 0;
242
0
            return Status::OK();
243
0
        }
244
245
2
        auto total = *n;
246
2
        bool result = false;
247
2
        size_t read_count = 0;
248
2
        CppType value;
249
6
        for (size_t i = 0; i < total; ++i) {
250
4
            ordinal_t ord = rowids[i] - page_first_ordinal;
251
4
            if (UNLIKELY(ord >= _num_elements)) {
252
0
                *n = read_count;
253
0
                return Status::OK();
254
0
            }
255
256
4
            _rle_decoder.Skip(ord - _cur_index);
257
4
            _cur_index = ord;
258
259
4
            result = _rle_decoder.Get(&value);
260
4
            _cur_index++;
261
4
            DCHECK(result);
262
4
            dst->insert_data((char*)(&value), SIZE_OF_TYPE);
263
4
            read_count++;
264
4
        }
265
2
        *n = read_count;
266
2
        return Status::OK();
267
2
    }
268
269
4
    size_t count() const override { return _num_elements; }
_ZNK5doris10segment_v214RlePageDecoderILNS_9FieldTypeE5EE5countEv
Line
Count
Source
269
3
    size_t count() const override { return _num_elements; }
_ZNK5doris10segment_v214RlePageDecoderILNS_9FieldTypeE24EE5countEv
Line
Count
Source
269
1
    size_t count() const override { return _num_elements; }
270
271
404
    size_t current_index() const override { return _cur_index; }
_ZNK5doris10segment_v214RlePageDecoderILNS_9FieldTypeE5EE13current_indexEv
Line
Count
Source
271
303
    size_t current_index() const override { return _cur_index; }
_ZNK5doris10segment_v214RlePageDecoderILNS_9FieldTypeE24EE13current_indexEv
Line
Count
Source
271
101
    size_t current_index() const override { return _cur_index; }
272
273
private:
274
    typedef typename TypeTraits<Type>::CppType CppType;
275
    enum { SIZE_OF_TYPE = TypeTraits<Type>::size };
276
277
    Slice _data;
278
    PageDecoderOptions _options;
279
    bool _parsed;
280
    uint32_t _num_elements;
281
    size_t _cur_index;
282
    int _bit_width;
283
    RleDecoder<CppType> _rle_decoder;
284
};
285
286
} // namespace segment_v2
287
} // namespace doris