Coverage Report

Created: 2026-10-18 22:52

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/root/doris/be/src/util/rle_encoding.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
#pragma once
18
19
#include <glog/logging.h>
20
21
#include <algorithm>
22
#include <cstdint>
23
#include <limits> // IWYU pragma: keep
24
25
#include "common/cast_set.h"
26
#include "util/bit_stream_utils.inline.h"
27
#include "util/bit_util.h"
28
29
namespace doris {
30
#include "common/compile_check_begin.h"
31
32
// Utility classes to do run length encoding (RLE) for fixed bit width values.  If runs
33
// are sufficiently long, RLE is used, otherwise, the values are just bit-packed
34
// (literal encoding).
35
// For both types of runs, there is a byte-aligned indicator which encodes the length
36
// of the run and the type of the run.
37
// This encoding has the benefit that when there aren't any long enough runs, values
38
// are always decoded at fixed (can be precomputed) bit offsets OR both the value and
39
// the run length are byte aligned. This allows for very efficient decoding
40
// implementations.
41
// The encoding is:
42
//    encoded-block := run*
43
//    run := literal-run | repeated-run
44
//    literal-run := literal-indicator < literal bytes >
45
//    repeated-run := repeated-indicator < repeated value. padded to byte boundary >
46
//    literal-indicator := varint_encode( number_of_groups << 1 | 1)
47
//    repeated-indicator := varint_encode( number_of_repetitions << 1 )
48
//
49
// Each run is preceded by a varint. The varint's least significant bit is
50
// used to indicate whether the run is a literal run or a repeated run. The rest
51
// of the varint is used to determine the length of the run (eg how many times the
52
// value repeats).
53
//
54
// In the case of literal runs, the run length is always a multiple of 8 (i.e. encode
55
// in groups of 8), so that no matter the bit-width of the value, the sequence will end
56
// on a byte boundary without padding.
57
// Given that we know it is a multiple of 8, we store the number of 8-groups rather than
58
// the actual number of encoded ints. (This means that the total number of encoded values
59
// can not be determined from the encoded data, since the number of values in the last
60
// group may not be a multiple of 8).
61
// There is a break-even point when it is more storage efficient to do run length
62
// encoding.  For 1 bit-width values, that point is 8 values.  They require 2 bytes
63
// for both the repeated encoding or the literal encoding.  This value can always
64
// be computed based on the bit-width.
65
// TODO: think about how to use this for strings.  The bit packing isn't quite the same.
66
//
67
// Examples with bit-width 1 (eg encoding booleans):
68
// ----------------------------------------
69
// 100 1s followed by 100 0s:
70
// <varint(100 << 1)> <1, padded to 1 byte> <varint(100 << 1)> <0, padded to 1 byte>
71
//  - (total 4 bytes)
72
//
73
// alternating 1s and 0s (200 total):
74
// 200 ints = 25 groups of 8
75
// <varint((25 << 1) | 1)> <25 bytes of values, bitpacked>
76
// (total 26 bytes, 1 byte overhead)
77
//
78
79
// Decoder class for RLE encoded data.
80
//
81
// NOTE: the encoded format does not have any length prefix or any other way of
82
// indicating that the encoded sequence ends at a certain point, so the Decoder
83
// methods may return some extra bits at the end before the read methods start
84
// to return 0/false.
85
template <typename T>
86
class RleDecoder {
87
public:
88
    // Create a decoder object. buffer/buffer_len is the decoded data.
89
    // bit_width is the width of each value (before encoding).
90
    RleDecoder(const uint8_t* buffer, int buffer_len, int bit_width)
91
1.52k
            : bit_reader_(buffer, buffer_len),
92
1.52k
              bit_width_(bit_width),
93
1.52k
              current_value_(0),
94
1.52k
              repeat_count_(0),
95
1.52k
              literal_count_(0),
96
1.52k
              rewind_state_(CANT_REWIND) {
97
1.52k
        DCHECK_GE(bit_width_, 1);
98
1.52k
        DCHECK_LE(bit_width_, 64);
99
1.52k
    }
_ZN5doris10RleDecoderIbEC2EPKhii
Line
Count
Source
91
738
            : bit_reader_(buffer, buffer_len),
92
738
              bit_width_(bit_width),
93
738
              current_value_(0),
94
738
              repeat_count_(0),
95
738
              literal_count_(0),
96
738
              rewind_state_(CANT_REWIND) {
97
738
        DCHECK_GE(bit_width_, 1);
98
        DCHECK_LE(bit_width_, 64);
99
738
    }
_ZN5doris10RleDecoderIhEC2EPKhii
Line
Count
Source
91
10
            : bit_reader_(buffer, buffer_len),
92
10
              bit_width_(bit_width),
93
10
              current_value_(0),
94
10
              repeat_count_(0),
95
10
              literal_count_(0),
96
10
              rewind_state_(CANT_REWIND) {
97
10
        DCHECK_GE(bit_width_, 1);
98
        DCHECK_LE(bit_width_, 64);
99
10
    }
_ZN5doris10RleDecoderImEC2EPKhii
Line
Count
Source
91
412
            : bit_reader_(buffer, buffer_len),
92
412
              bit_width_(bit_width),
93
412
              current_value_(0),
94
412
              repeat_count_(0),
95
412
              literal_count_(0),
96
412
              rewind_state_(CANT_REWIND) {
97
412
        DCHECK_GE(bit_width_, 1);
98
        DCHECK_LE(bit_width_, 64);
99
412
    }
_ZN5doris10RleDecoderIsEC2EPKhii
Line
Count
Source
91
361
            : bit_reader_(buffer, buffer_len),
92
361
              bit_width_(bit_width),
93
361
              current_value_(0),
94
361
              repeat_count_(0),
95
361
              literal_count_(0),
96
361
              rewind_state_(CANT_REWIND) {
97
361
        DCHECK_GE(bit_width_, 1);
98
        DCHECK_LE(bit_width_, 64);
99
361
    }
100
101
29.0k
    RleDecoder() {}
_ZN5doris10RleDecoderIhEC2Ev
Line
Count
Source
101
10
    RleDecoder() {}
_ZN5doris10RleDecoderIsEC2Ev
Line
Count
Source
101
433
    RleDecoder() {}
_ZN5doris10RleDecoderIbEC2Ev
Line
Count
Source
101
28.6k
    RleDecoder() {}
102
103
    // Skip n values, and returns the number of non-zero entries skipped.
104
    size_t Skip(size_t to_skip);
105
106
    // Gets the next value.  Returns false if there are no more.
107
    bool Get(T* val);
108
109
    // Seek to the previous value.
110
    void RewindOne();
111
112
    // Gets the next run of the same 'val'. Returns 0 if there is no
113
    // more data to be decoded. Will return a run of at most 'max_run'
114
    // values. If there are more values than this, the next call to
115
    // GetNextRun will return more from the same run.
116
    size_t GetNextRun(T* val, size_t max_run);
117
118
    size_t get_values(T* values, size_t num_values);
119
120
    // Get the count of current repeated value
121
    size_t repeated_count();
122
123
    // Get current repeated value, make sure that count equals repeated_count()
124
    T get_repeated_value(size_t count);
125
126
0
    const BitReader& bit_reader() const { return bit_reader_; }
127
128
private:
129
    bool ReadHeader();
130
131
    enum RewindState { REWIND_LITERAL, REWIND_RUN, CANT_REWIND };
132
133
    BitReader bit_reader_;
134
    int bit_width_;
135
    uint64_t current_value_;
136
    uint32_t repeat_count_;
137
    uint32_t literal_count_;
138
    RewindState rewind_state_;
139
};
140
141
// Class to incrementally build the rle data.
142
// The encoding has two modes: encoding repeated runs and literal runs.
143
// If the run is sufficiently short, it is more efficient to encode as a literal run.
144
// This class does so by buffering 8 values at a time.  If they are not all the same
145
// they are added to the literal run.  If they are the same, they are added to the
146
// repeated run.  When we switch modes, the previous run is flushed out.
147
template <typename T>
148
class RleEncoder {
149
public:
150
    // buffer: buffer to write bits to.
151
    // bit_width: max number of bits for value.
152
    // TODO: consider adding a min_repeated_run_length so the caller can control
153
    // when values should be encoded as repeated runs.  Currently this is derived
154
    // based on the bit_width, which can determine a storage optimal choice.
155
    explicit RleEncoder(faststring* buffer, int bit_width)
156
11.0M
            : bit_width_(bit_width), bit_writer_(buffer) {
157
11.0M
        DCHECK_GE(bit_width_, 1);
158
11.0M
        DCHECK_LE(bit_width_, 64);
159
11.0M
        Clear();
160
11.0M
    }
_ZN5doris10RleEncoderIjEC2EPNS_10faststringEi
Line
Count
Source
156
45.2k
            : bit_width_(bit_width), bit_writer_(buffer) {
157
45.2k
        DCHECK_GE(bit_width_, 1);
158
        DCHECK_LE(bit_width_, 64);
159
45.2k
        Clear();
160
45.2k
    }
_ZN5doris10RleEncoderIbEC2EPNS_10faststringEi
Line
Count
Source
156
6.86k
            : bit_width_(bit_width), bit_writer_(buffer) {
157
6.86k
        DCHECK_GE(bit_width_, 1);
158
        DCHECK_LE(bit_width_, 64);
159
6.86k
        Clear();
160
6.86k
    }
_ZN5doris10RleEncoderIhEC2EPNS_10faststringEi
Line
Count
Source
156
5
            : bit_width_(bit_width), bit_writer_(buffer) {
157
5
        DCHECK_GE(bit_width_, 1);
158
        DCHECK_LE(bit_width_, 64);
159
5
        Clear();
160
5
    }
_ZN5doris10RleEncoderImEC2EPNS_10faststringEi
Line
Count
Source
156
11.0M
            : bit_width_(bit_width), bit_writer_(buffer) {
157
11.0M
        DCHECK_GE(bit_width_, 1);
158
        DCHECK_LE(bit_width_, 64);
159
11.0M
        Clear();
160
11.0M
    }
161
162
    // The largest number of values a single repeated run can describe.
163
    //
164
    // A repeated run is written as a vlq-encoded indicator holding
165
    // `run_length << 1` (see FlushRepeatedRun) and read back into a uint32_t by
166
    // BitReader::GetVlqInt. Capping the run length here keeps the indicator
167
    // inside int32_t's positive range, which is exactly the range every released
168
    // version could already encode, so the output stays byte-identical for any
169
    // run length that used to work.
170
    static constexpr int64_t MAX_VALUES_PER_REPEATED_RUN = (int64_t {1} << 30) - 1;
171
172
    // Reserve 'num_bytes' bytes for a plain encoded header, set each
173
    // byte with 'val': this is used for the RLE-encoded data blocks in
174
    // order to be able to able to store the initial ordinal position
175
    // and number of elements. This is a part of RleEncoder in order to
176
    // maintain the correct offset in 'buffer'.
177
    void Reserve(int num_bytes, uint8_t val);
178
179
    // Encode value. This value must be representable with bit_width_ bits.
180
    void Put(T value, size_t run_length = 1);
181
182
    // Flushes any pending values to the underlying buffer.
183
    // Returns the total number of bytes written
184
    int Flush();
185
186
    // Resets all the state in the encoder.
187
    void Clear();
188
189
313
    int32_t len() const { return bit_writer_.bytes_written(); }
_ZNK5doris10RleEncoderIbE3lenEv
Line
Count
Source
189
306
    int32_t len() const { return bit_writer_.bytes_written(); }
_ZNK5doris10RleEncoderIhE3lenEv
Line
Count
Source
189
7
    int32_t len() const { return bit_writer_.bytes_written(); }
190
191
private:
192
    // Flushes any buffered values.  If this is part of a repeated run, this is largely
193
    // a no-op.
194
    // If it is part of a literal run, this will call FlushLiteralRun, which writes
195
    // out the buffered literal values.
196
    // If 'done' is true, the current run would be written even if it would normally
197
    // have been buffered more.  This should only be called at the end, when the
198
    // encoder has received all values even if it would normally continue to be
199
    // buffered.
200
    void FlushBufferedValues(bool done);
201
202
    // Flushes literal values to the underlying buffer.  If update_indicator_byte,
203
    // then the current literal run is complete and the indicator byte is updated.
204
    void FlushLiteralRun(bool update_indicator_byte);
205
206
    // Flushes a repeated run to the underlying buffer.
207
    void FlushRepeatedRun();
208
209
    // Number of bits needed to encode the value.
210
    const int bit_width_;
211
212
    // Underlying buffer.
213
    BitWriter bit_writer_;
214
215
    // We need to buffer at most 8 values for literals.  This happens when the
216
    // bit_width is 1 (so 8 values fit in one byte).
217
    // TODO: generalize this to other bit widths
218
    uint64_t buffered_values_[8];
219
220
    // Number of values in buffered_values_
221
    int num_buffered_values_;
222
223
    // The current (also last) value that was written and the count of how
224
    // many times in a row that value has been seen.  This is maintained even
225
    // if we are in a literal run.  If the repeat_count_ get high enough, we switch
226
    // to encoding repeated runs.
227
    uint64_t current_value_;
228
    int64_t repeat_count_;
229
230
    // Number of literals in the current run.  This does not include the literals
231
    // that might be in buffered_values_.  Only after we've got a group big enough
232
    // can we decide if they should part of the literal_count_ or repeat_count_
233
    int literal_count_;
234
235
    // Index of a byte in the underlying buffer that stores the indicator byte.
236
    // This is reserved as soon as we need a literal run but the value is written
237
    // when the literal run is complete. We maintain an index rather than a pointer
238
    // into the underlying buffer because the pointer value may become invalid if
239
    // the underlying buffer is resized.
240
    int literal_indicator_byte_idx_;
241
};
242
243
template <typename T>
244
365k
bool RleDecoder<T>::ReadHeader() {
245
365k
    DCHECK(bit_reader_.is_initialized());
246
365k
    if (literal_count_ == 0 && repeat_count_ == 0) [[unlikely]] {
247
        // Read the next run's indicator int, it could be a literal or repeated run
248
        // The int is encoded as a vlq-encoded value.
249
27.5k
        uint32_t indicator_value = 0;
250
27.5k
        bool result = bit_reader_.GetVlqInt(&indicator_value);
251
27.5k
        if (!result) [[unlikely]] {
252
348
            return false;
253
348
        }
254
255
        // lsb indicates if it is a literal run or repeated run
256
27.1k
        bool is_literal = indicator_value & 1;
257
27.1k
        if (is_literal) {
258
3.36k
            literal_count_ = (indicator_value >> 1) * 8;
259
3.36k
            DCHECK_GT(literal_count_, 0);
260
23.8k
        } else {
261
23.8k
            repeat_count_ = indicator_value >> 1;
262
23.8k
            DCHECK_GT(repeat_count_, 0);
263
23.8k
            bool result1 = bit_reader_.GetAligned<T>(BitUtil::Ceil(bit_width_, 8),
264
23.8k
                                                     reinterpret_cast<T*>(&current_value_));
265
23.8k
            DCHECK(result1);
266
23.8k
        }
267
27.1k
    }
268
364k
    return true;
269
365k
}
_ZN5doris10RleDecoderIsE10ReadHeaderEv
Line
Count
Source
244
18.2k
bool RleDecoder<T>::ReadHeader() {
245
18.2k
    DCHECK(bit_reader_.is_initialized());
246
18.2k
    if (literal_count_ == 0 && repeat_count_ == 0) [[unlikely]] {
247
        // Read the next run's indicator int, it could be a literal or repeated run
248
        // The int is encoded as a vlq-encoded value.
249
423
        uint32_t indicator_value = 0;
250
423
        bool result = bit_reader_.GetVlqInt(&indicator_value);
251
423
        if (!result) [[unlikely]] {
252
36
            return false;
253
36
        }
254
255
        // lsb indicates if it is a literal run or repeated run
256
387
        bool is_literal = indicator_value & 1;
257
387
        if (is_literal) {
258
233
            literal_count_ = (indicator_value >> 1) * 8;
259
233
            DCHECK_GT(literal_count_, 0);
260
233
        } else {
261
154
            repeat_count_ = indicator_value >> 1;
262
154
            DCHECK_GT(repeat_count_, 0);
263
154
            bool result1 = bit_reader_.GetAligned<T>(BitUtil::Ceil(bit_width_, 8),
264
154
                                                     reinterpret_cast<T*>(&current_value_));
265
154
            DCHECK(result1);
266
154
        }
267
387
    }
268
18.1k
    return true;
269
18.2k
}
_ZN5doris10RleDecoderIbE10ReadHeaderEv
Line
Count
Source
244
97.8k
bool RleDecoder<T>::ReadHeader() {
245
97.8k
    DCHECK(bit_reader_.is_initialized());
246
97.8k
    if (literal_count_ == 0 && repeat_count_ == 0) [[unlikely]] {
247
        // Read the next run's indicator int, it could be a literal or repeated run
248
        // The int is encoded as a vlq-encoded value.
249
24.0k
        uint32_t indicator_value = 0;
250
24.0k
        bool result = bit_reader_.GetVlqInt(&indicator_value);
251
24.0k
        if (!result) [[unlikely]] {
252
309
            return false;
253
309
        }
254
255
        // lsb indicates if it is a literal run or repeated run
256
23.7k
        bool is_literal = indicator_value & 1;
257
23.7k
        if (is_literal) {
258
1.99k
            literal_count_ = (indicator_value >> 1) * 8;
259
1.99k
            DCHECK_GT(literal_count_, 0);
260
21.7k
        } else {
261
21.7k
            repeat_count_ = indicator_value >> 1;
262
21.7k
            DCHECK_GT(repeat_count_, 0);
263
21.7k
            bool result1 = bit_reader_.GetAligned<T>(BitUtil::Ceil(bit_width_, 8),
264
21.7k
                                                     reinterpret_cast<T*>(&current_value_));
265
21.7k
            DCHECK(result1);
266
21.7k
        }
267
23.7k
    }
268
97.5k
    return true;
269
97.8k
}
_ZN5doris10RleDecoderIhE10ReadHeaderEv
Line
Count
Source
244
759
bool RleDecoder<T>::ReadHeader() {
245
759
    DCHECK(bit_reader_.is_initialized());
246
759
    if (literal_count_ == 0 && repeat_count_ == 0) [[unlikely]] {
247
        // Read the next run's indicator int, it could be a literal or repeated run
248
        // The int is encoded as a vlq-encoded value.
249
12
        uint32_t indicator_value = 0;
250
12
        bool result = bit_reader_.GetVlqInt(&indicator_value);
251
12
        if (!result) [[unlikely]] {
252
0
            return false;
253
0
        }
254
255
        // lsb indicates if it is a literal run or repeated run
256
12
        bool is_literal = indicator_value & 1;
257
12
        if (is_literal) {
258
9
            literal_count_ = (indicator_value >> 1) * 8;
259
9
            DCHECK_GT(literal_count_, 0);
260
9
        } else {
261
3
            repeat_count_ = indicator_value >> 1;
262
3
            DCHECK_GT(repeat_count_, 0);
263
3
            bool result1 = bit_reader_.GetAligned<T>(BitUtil::Ceil(bit_width_, 8),
264
3
                                                     reinterpret_cast<T*>(&current_value_));
265
3
            DCHECK(result1);
266
3
        }
267
12
    }
268
759
    return true;
269
759
}
_ZN5doris10RleDecoderImE10ReadHeaderEv
Line
Count
Source
244
248k
bool RleDecoder<T>::ReadHeader() {
245
248k
    DCHECK(bit_reader_.is_initialized());
246
248k
    if (literal_count_ == 0 && repeat_count_ == 0) [[unlikely]] {
247
        // Read the next run's indicator int, it could be a literal or repeated run
248
        // The int is encoded as a vlq-encoded value.
249
3.07k
        uint32_t indicator_value = 0;
250
3.07k
        bool result = bit_reader_.GetVlqInt(&indicator_value);
251
3.07k
        if (!result) [[unlikely]] {
252
3
            return false;
253
3
        }
254
255
        // lsb indicates if it is a literal run or repeated run
256
3.07k
        bool is_literal = indicator_value & 1;
257
3.07k
        if (is_literal) {
258
1.12k
            literal_count_ = (indicator_value >> 1) * 8;
259
1.12k
            DCHECK_GT(literal_count_, 0);
260
1.94k
        } else {
261
1.94k
            repeat_count_ = indicator_value >> 1;
262
1.94k
            DCHECK_GT(repeat_count_, 0);
263
1.94k
            bool result1 = bit_reader_.GetAligned<T>(BitUtil::Ceil(bit_width_, 8),
264
1.94k
                                                     reinterpret_cast<T*>(&current_value_));
265
1.94k
            DCHECK(result1);
266
1.94k
        }
267
3.07k
    }
268
248k
    return true;
269
248k
}
270
271
template <typename T>
272
274k
bool RleDecoder<T>::Get(T* val) {
273
274k
    DCHECK(bit_reader_.is_initialized());
274
274k
    if (!ReadHeader()) [[unlikely]] {
275
5
        return false;
276
5
    }
277
278
274k
    if (repeat_count_ > 0) [[likely]] {
279
169k
        *val = cast_set<T>(current_value_);
280
169k
        --repeat_count_;
281
169k
        rewind_state_ = REWIND_RUN;
282
169k
    } else {
283
104k
        DCHECK(literal_count_ > 0);
284
104k
        bool result = bit_reader_.GetValue(bit_width_, val);
285
104k
        DCHECK(result);
286
104k
        --literal_count_;
287
104k
        rewind_state_ = REWIND_LITERAL;
288
104k
    }
289
290
274k
    return true;
291
274k
}
_ZN5doris10RleDecoderIsE3GetEPs
Line
Count
Source
272
14.5k
bool RleDecoder<T>::Get(T* val) {
273
14.5k
    DCHECK(bit_reader_.is_initialized());
274
14.5k
    if (!ReadHeader()) [[unlikely]] {
275
0
        return false;
276
0
    }
277
278
14.5k
    if (repeat_count_ > 0) [[likely]] {
279
10
        *val = cast_set<T>(current_value_);
280
10
        --repeat_count_;
281
10
        rewind_state_ = REWIND_RUN;
282
14.5k
    } else {
283
14.5k
        DCHECK(literal_count_ > 0);
284
14.5k
        bool result = bit_reader_.GetValue(bit_width_, val);
285
14.5k
        DCHECK(result);
286
14.5k
        --literal_count_;
287
14.5k
        rewind_state_ = REWIND_LITERAL;
288
14.5k
    }
289
290
14.5k
    return true;
291
14.5k
}
_ZN5doris10RleDecoderIbE3GetEPb
Line
Count
Source
272
10.4k
bool RleDecoder<T>::Get(T* val) {
273
10.4k
    DCHECK(bit_reader_.is_initialized());
274
10.4k
    if (!ReadHeader()) [[unlikely]] {
275
2
        return false;
276
2
    }
277
278
10.4k
    if (repeat_count_ > 0) [[likely]] {
279
10.3k
        *val = cast_set<T>(current_value_);
280
10.3k
        --repeat_count_;
281
10.3k
        rewind_state_ = REWIND_RUN;
282
10.3k
    } else {
283
111
        DCHECK(literal_count_ > 0);
284
111
        bool result = bit_reader_.GetValue(bit_width_, val);
285
111
        DCHECK(result);
286
111
        --literal_count_;
287
111
        rewind_state_ = REWIND_LITERAL;
288
111
    }
289
290
10.4k
    return true;
291
10.4k
}
_ZN5doris10RleDecoderIhE3GetEPh
Line
Count
Source
272
753
bool RleDecoder<T>::Get(T* val) {
273
753
    DCHECK(bit_reader_.is_initialized());
274
753
    if (!ReadHeader()) [[unlikely]] {
275
0
        return false;
276
0
    }
277
278
753
    if (repeat_count_ > 0) [[likely]] {
279
350
        *val = cast_set<T>(current_value_);
280
350
        --repeat_count_;
281
350
        rewind_state_ = REWIND_RUN;
282
403
    } else {
283
403
        DCHECK(literal_count_ > 0);
284
403
        bool result = bit_reader_.GetValue(bit_width_, val);
285
403
        DCHECK(result);
286
403
        --literal_count_;
287
403
        rewind_state_ = REWIND_LITERAL;
288
403
    }
289
290
753
    return true;
291
753
}
_ZN5doris10RleDecoderImE3GetEPm
Line
Count
Source
272
248k
bool RleDecoder<T>::Get(T* val) {
273
248k
    DCHECK(bit_reader_.is_initialized());
274
248k
    if (!ReadHeader()) [[unlikely]] {
275
3
        return false;
276
3
    }
277
278
248k
    if (repeat_count_ > 0) [[likely]] {
279
159k
        *val = cast_set<T>(current_value_);
280
159k
        --repeat_count_;
281
159k
        rewind_state_ = REWIND_RUN;
282
159k
    } else {
283
89.1k
        DCHECK(literal_count_ > 0);
284
89.1k
        bool result = bit_reader_.GetValue(bit_width_, val);
285
89.1k
        DCHECK(result);
286
89.1k
        --literal_count_;
287
89.1k
        rewind_state_ = REWIND_LITERAL;
288
89.1k
    }
289
290
248k
    return true;
291
248k
}
292
293
template <typename T>
294
518
void RleDecoder<T>::RewindOne() {
295
518
    DCHECK(bit_reader_.is_initialized());
296
297
518
    switch (rewind_state_) {
298
0
    case CANT_REWIND:
299
0
        throw Exception(Status::FatalError("Can't rewind more than once after each read!"));
300
0
        break;
301
4
    case REWIND_RUN:
302
4
        ++repeat_count_;
303
4
        break;
304
514
    case REWIND_LITERAL: {
305
514
        bit_reader_.Rewind(bit_width_);
306
514
        ++literal_count_;
307
514
        break;
308
0
    }
309
518
    }
310
311
518
    rewind_state_ = CANT_REWIND;
312
518
}
313
314
template <typename T>
315
67.7k
size_t RleDecoder<T>::GetNextRun(T* val, size_t max_run) {
316
67.7k
    DCHECK(bit_reader_.is_initialized());
317
67.7k
    DCHECK_GT(max_run, 0);
318
67.7k
    size_t ret = 0;
319
67.7k
    size_t rem = max_run;
320
90.8k
    while (ReadHeader()) {
321
90.5k
        if (repeat_count_ > 0) [[likely]] {
322
46.2k
            if (ret > 0 && *val != current_value_) [[unlikely]] {
323
19.9k
                return ret;
324
19.9k
            }
325
26.2k
            *val = cast_set<T>(current_value_);
326
26.2k
            if (repeat_count_ >= rem) {
327
                // The next run is longer than the amount of remaining data
328
                // that the caller wants to read. Only consume it partially.
329
4.94k
                repeat_count_ -= rem;
330
4.94k
                ret += rem;
331
4.94k
                return ret;
332
4.94k
            }
333
21.3k
            ret += repeat_count_;
334
21.3k
            rem -= repeat_count_;
335
21.3k
            repeat_count_ = 0;
336
44.2k
        } else {
337
44.2k
            DCHECK(literal_count_ > 0);
338
44.2k
            if (ret == 0) {
339
42.7k
                bool has_more = bit_reader_.GetValue(bit_width_, val);
340
42.7k
                DCHECK(has_more);
341
42.7k
                literal_count_--;
342
42.7k
                ret++;
343
42.7k
                rem--;
344
42.7k
            }
345
346
116k
            while (literal_count_ > 0) {
347
115k
                bool result = bit_reader_.GetValue(bit_width_, &current_value_);
348
115k
                DCHECK(result);
349
115k
                if (current_value_ != *val || rem == 0) {
350
42.5k
                    bit_reader_.Rewind(bit_width_);
351
42.5k
                    return ret;
352
42.5k
                }
353
72.5k
                ret++;
354
72.5k
                rem--;
355
72.5k
                literal_count_--;
356
72.5k
            }
357
44.2k
        }
358
90.5k
    }
359
343
    return ret;
360
67.7k
}
_ZN5doris10RleDecoderIsE10GetNextRunEPsm
Line
Count
Source
315
3.43k
size_t RleDecoder<T>::GetNextRun(T* val, size_t max_run) {
316
3.43k
    DCHECK(bit_reader_.is_initialized());
317
3.43k
    DCHECK_GT(max_run, 0);
318
3.43k
    size_t ret = 0;
319
3.43k
    size_t rem = max_run;
320
3.48k
    while (ReadHeader()) {
321
3.44k
        if (repeat_count_ > 0) [[likely]] {
322
496
            if (ret > 0 && *val != current_value_) [[unlikely]] {
323
0
                return ret;
324
0
            }
325
496
            *val = cast_set<T>(current_value_);
326
496
            if (repeat_count_ >= rem) {
327
                // The next run is longer than the amount of remaining data
328
                // that the caller wants to read. Only consume it partially.
329
496
                repeat_count_ -= rem;
330
496
                ret += rem;
331
496
                return ret;
332
496
            }
333
0
            ret += repeat_count_;
334
0
            rem -= repeat_count_;
335
0
            repeat_count_ = 0;
336
2.94k
        } else {
337
2.94k
            DCHECK(literal_count_ > 0);
338
2.94k
            if (ret == 0) {
339
2.94k
                bool has_more = bit_reader_.GetValue(bit_width_, val);
340
2.94k
                DCHECK(has_more);
341
2.94k
                literal_count_--;
342
2.94k
                ret++;
343
2.94k
                rem--;
344
2.94k
            }
345
346
8.27k
            while (literal_count_ > 0) {
347
8.23k
                bool result = bit_reader_.GetValue(bit_width_, &current_value_);
348
8.23k
                DCHECK(result);
349
8.23k
                if (current_value_ != *val || rem == 0) {
350
2.90k
                    bit_reader_.Rewind(bit_width_);
351
2.90k
                    return ret;
352
2.90k
                }
353
5.32k
                ret++;
354
5.32k
                rem--;
355
5.32k
                literal_count_--;
356
5.32k
            }
357
2.94k
        }
358
3.44k
    }
359
36
    return ret;
360
3.43k
}
_ZN5doris10RleDecoderIbE10GetNextRunEPbm
Line
Count
Source
315
64.3k
size_t RleDecoder<T>::GetNextRun(T* val, size_t max_run) {
316
64.3k
    DCHECK(bit_reader_.is_initialized());
317
64.3k
    DCHECK_GT(max_run, 0);
318
64.3k
    size_t ret = 0;
319
64.3k
    size_t rem = max_run;
320
87.3k
    while (ReadHeader()) {
321
87.0k
        if (repeat_count_ > 0) [[likely]] {
322
45.7k
            if (ret > 0 && *val != current_value_) [[unlikely]] {
323
19.9k
                return ret;
324
19.9k
            }
325
25.7k
            *val = cast_set<T>(current_value_);
326
25.7k
            if (repeat_count_ >= rem) {
327
                // The next run is longer than the amount of remaining data
328
                // that the caller wants to read. Only consume it partially.
329
4.45k
                repeat_count_ -= rem;
330
4.45k
                ret += rem;
331
4.45k
                return ret;
332
4.45k
            }
333
21.3k
            ret += repeat_count_;
334
21.3k
            rem -= repeat_count_;
335
21.3k
            repeat_count_ = 0;
336
41.3k
        } else {
337
41.3k
            DCHECK(literal_count_ > 0);
338
41.3k
            if (ret == 0) {
339
39.8k
                bool has_more = bit_reader_.GetValue(bit_width_, val);
340
39.8k
                DCHECK(has_more);
341
39.8k
                literal_count_--;
342
39.8k
                ret++;
343
39.8k
                rem--;
344
39.8k
            }
345
346
108k
            while (literal_count_ > 0) {
347
106k
                bool result = bit_reader_.GetValue(bit_width_, &current_value_);
348
106k
                DCHECK(result);
349
106k
                if (current_value_ != *val || rem == 0) {
350
39.6k
                    bit_reader_.Rewind(bit_width_);
351
39.6k
                    return ret;
352
39.6k
                }
353
67.2k
                ret++;
354
67.2k
                rem--;
355
67.2k
                literal_count_--;
356
67.2k
            }
357
41.3k
        }
358
87.0k
    }
359
307
    return ret;
360
64.3k
}
361
362
template <typename T>
363
863
size_t RleDecoder<T>::get_values(T* values, size_t num_values) {
364
863
    size_t read_num = 0;
365
1.60k
    while (read_num < num_values) {
366
737
        size_t read_this_time = num_values - read_num;
367
368
737
        if (LIKELY(repeat_count_ > 0)) {
369
37
            read_this_time = std::min((size_t)repeat_count_, read_this_time);
370
37
            std::fill(values, values + read_this_time, current_value_);
371
37
            values += read_this_time;
372
37
            repeat_count_ -= read_this_time;
373
37
            read_num += read_this_time;
374
700
        } else if (literal_count_ > 0) {
375
548
            read_this_time = std::min((size_t)literal_count_, read_this_time);
376
22.8k
            for (int i = 0; i < read_this_time; ++i) {
377
22.2k
                bool result = bit_reader_.GetValue(bit_width_, values);
378
22.2k
                DCHECK(result);
379
22.2k
                values++;
380
22.2k
            }
381
548
            literal_count_ -= read_this_time;
382
548
            read_num += read_this_time;
383
548
        } else {
384
152
            if (!ReadHeader()) {
385
0
                return read_num;
386
0
            }
387
152
        }
388
737
    }
389
863
    return read_num;
390
863
}
_ZN5doris10RleDecoderIhE10get_valuesEPhm
Line
Count
Source
363
5
size_t RleDecoder<T>::get_values(T* values, size_t num_values) {
364
5
    size_t read_num = 0;
365
14
    while (read_num < num_values) {
366
9
        size_t read_this_time = num_values - read_num;
367
368
9
        if (LIKELY(repeat_count_ > 0)) {
369
0
            read_this_time = std::min((size_t)repeat_count_, read_this_time);
370
0
            std::fill(values, values + read_this_time, current_value_);
371
0
            values += read_this_time;
372
0
            repeat_count_ -= read_this_time;
373
0
            read_num += read_this_time;
374
9
        } else if (literal_count_ > 0) {
375
5
            read_this_time = std::min((size_t)literal_count_, read_this_time);
376
40
            for (int i = 0; i < read_this_time; ++i) {
377
35
                bool result = bit_reader_.GetValue(bit_width_, values);
378
35
                DCHECK(result);
379
35
                values++;
380
35
            }
381
5
            literal_count_ -= read_this_time;
382
5
            read_num += read_this_time;
383
5
        } else {
384
4
            if (!ReadHeader()) {
385
0
                return read_num;
386
0
            }
387
4
        }
388
9
    }
389
5
    return read_num;
390
5
}
_ZN5doris10RleDecoderIsE10get_valuesEPsm
Line
Count
Source
363
858
size_t RleDecoder<T>::get_values(T* values, size_t num_values) {
364
858
    size_t read_num = 0;
365
1.58k
    while (read_num < num_values) {
366
728
        size_t read_this_time = num_values - read_num;
367
368
728
        if (LIKELY(repeat_count_ > 0)) {
369
37
            read_this_time = std::min((size_t)repeat_count_, read_this_time);
370
37
            std::fill(values, values + read_this_time, current_value_);
371
37
            values += read_this_time;
372
37
            repeat_count_ -= read_this_time;
373
37
            read_num += read_this_time;
374
691
        } else if (literal_count_ > 0) {
375
543
            read_this_time = std::min((size_t)literal_count_, read_this_time);
376
22.8k
            for (int i = 0; i < read_this_time; ++i) {
377
22.2k
                bool result = bit_reader_.GetValue(bit_width_, values);
378
22.2k
                DCHECK(result);
379
22.2k
                values++;
380
22.2k
            }
381
543
            literal_count_ -= read_this_time;
382
543
            read_num += read_this_time;
383
543
        } else {
384
148
            if (!ReadHeader()) {
385
0
                return read_num;
386
0
            }
387
148
        }
388
728
    }
389
858
    return read_num;
390
858
}
391
392
template <typename T>
393
size_t RleDecoder<T>::repeated_count() {
394
    if (repeat_count_ > 0) {
395
        return repeat_count_;
396
    }
397
    if (literal_count_ == 0) {
398
        ReadHeader();
399
    }
400
    return repeat_count_;
401
}
402
403
template <typename T>
404
T RleDecoder<T>::get_repeated_value(size_t count) {
405
    DCHECK_GE(repeat_count_, count);
406
    repeat_count_ -= count;
407
    return current_value_;
408
}
409
410
template <typename T>
411
16
size_t RleDecoder<T>::Skip(size_t to_skip) {
412
16
    DCHECK(bit_reader_.is_initialized());
413
414
16
    size_t set_count = 0;
415
31
    while (to_skip > 0) {
416
15
        bool result = ReadHeader();
417
15
        DCHECK(result);
418
419
15
        if (repeat_count_ > 0) [[likely]] {
420
7
            size_t nskip = (repeat_count_ < to_skip) ? repeat_count_ : to_skip;
421
7
            repeat_count_ -= nskip;
422
7
            to_skip -= nskip;
423
7
            if (current_value_ != 0) {
424
3
                set_count += nskip;
425
3
            }
426
8
        } else {
427
8
            DCHECK(literal_count_ > 0);
428
8
            size_t nskip = (literal_count_ < to_skip) ? literal_count_ : to_skip;
429
8
            literal_count_ -= nskip;
430
8
            to_skip -= nskip;
431
69
            for (; nskip > 0; nskip--) {
432
61
                T value = 0;
433
61
                bool result1 = bit_reader_.GetValue(bit_width_, &value);
434
61
                DCHECK(result1);
435
61
                if (value != 0) {
436
29
                    set_count++;
437
29
                }
438
61
            }
439
8
        }
440
15
    }
441
16
    return set_count;
442
16
}
_ZN5doris10RleDecoderIbE4SkipEm
Line
Count
Source
411
12
size_t RleDecoder<T>::Skip(size_t to_skip) {
412
12
    DCHECK(bit_reader_.is_initialized());
413
414
12
    size_t set_count = 0;
415
25
    while (to_skip > 0) {
416
13
        bool result = ReadHeader();
417
13
        DCHECK(result);
418
419
13
        if (repeat_count_ > 0) [[likely]] {
420
7
            size_t nskip = (repeat_count_ < to_skip) ? repeat_count_ : to_skip;
421
7
            repeat_count_ -= nskip;
422
7
            to_skip -= nskip;
423
7
            if (current_value_ != 0) {
424
3
                set_count += nskip;
425
3
            }
426
7
        } else {
427
6
            DCHECK(literal_count_ > 0);
428
6
            size_t nskip = (literal_count_ < to_skip) ? literal_count_ : to_skip;
429
6
            literal_count_ -= nskip;
430
6
            to_skip -= nskip;
431
62
            for (; nskip > 0; nskip--) {
432
56
                T value = 0;
433
56
                bool result1 = bit_reader_.GetValue(bit_width_, &value);
434
56
                DCHECK(result1);
435
56
                if (value != 0) {
436
27
                    set_count++;
437
27
                }
438
56
            }
439
6
        }
440
13
    }
441
12
    return set_count;
442
12
}
_ZN5doris10RleDecoderIhE4SkipEm
Line
Count
Source
411
4
size_t RleDecoder<T>::Skip(size_t to_skip) {
412
4
    DCHECK(bit_reader_.is_initialized());
413
414
4
    size_t set_count = 0;
415
6
    while (to_skip > 0) {
416
2
        bool result = ReadHeader();
417
2
        DCHECK(result);
418
419
2
        if (repeat_count_ > 0) [[likely]] {
420
0
            size_t nskip = (repeat_count_ < to_skip) ? repeat_count_ : to_skip;
421
0
            repeat_count_ -= nskip;
422
0
            to_skip -= nskip;
423
0
            if (current_value_ != 0) {
424
0
                set_count += nskip;
425
0
            }
426
2
        } else {
427
2
            DCHECK(literal_count_ > 0);
428
2
            size_t nskip = (literal_count_ < to_skip) ? literal_count_ : to_skip;
429
2
            literal_count_ -= nskip;
430
2
            to_skip -= nskip;
431
7
            for (; nskip > 0; nskip--) {
432
5
                T value = 0;
433
5
                bool result1 = bit_reader_.GetValue(bit_width_, &value);
434
5
                DCHECK(result1);
435
5
                if (value != 0) {
436
2
                    set_count++;
437
2
                }
438
5
            }
439
2
        }
440
2
    }
441
4
    return set_count;
442
4
}
443
444
// This function buffers input values 8 at a time.  After seeing all 8 values,
445
// it decides whether they should be encoded as a literal or repeated run.
446
template <typename T>
447
20.3M
void RleEncoder<T>::Put(T value, size_t run_length) {
448
20.3M
    DCHECK(bit_width_ == 64 || value < (1LL << bit_width_));
449
450
    // Fast path: if this is a continuation of the current repeated run and
451
    // we've already buffered enough values, just increment repeat_count_
452
20.3M
    if (current_value_ == value && repeat_count_ >= 8 && run_length > 0) [[likely]] {
453
790k
        repeat_count_ += static_cast<int64_t>(run_length);
454
790k
        return;
455
790k
    }
456
457
    // Handle run_length > 1 more efficiently
458
38.2M
    while (run_length > 0) {
459
37.6M
        if (current_value_ == value) [[likely]] {
460
            // Need to buffer values until we reach 8
461
19.2M
            size_t to_buffer = std::min(run_length, size_t(8 - num_buffered_values_));
462
153M
            for (size_t i = 0; i < to_buffer; ++i) {
463
134M
                buffered_values_[num_buffered_values_++] = value;
464
134M
                ++repeat_count_;
465
134M
            }
466
19.2M
            run_length -= to_buffer;
467
19.2M
            if (num_buffered_values_ == 8) {
468
19.0M
                DCHECK_EQ(literal_count_ % 8, 0);
469
19.0M
                FlushBufferedValues(false);
470
                // After flushing, if we still have a repeated run and more values,
471
                // we can add them directly to repeat_count_
472
19.0M
                if (repeat_count_ >= 8 && run_length > 0) {
473
19.0M
                    repeat_count_ += static_cast<int64_t>(run_length);
474
19.0M
                    return;
475
19.0M
                }
476
19.0M
            }
477
19.2M
        } else {
478
            // Value changed
479
18.3M
            if (repeat_count_ >= 8) {
480
                // We had a run that was long enough but it has ended.  Flush the
481
                // current repeated run.
482
8.02M
                DCHECK_EQ(literal_count_, 0);
483
8.02M
                FlushRepeatedRun();
484
8.02M
            }
485
18.3M
            repeat_count_ = 1;
486
18.3M
            current_value_ = value;
487
488
18.3M
            buffered_values_[num_buffered_values_++] = value;
489
18.3M
            --run_length;
490
18.3M
            if (num_buffered_values_ == 8) {
491
16.5k
                DCHECK_EQ(literal_count_ % 8, 0);
492
16.5k
                FlushBufferedValues(false);
493
16.5k
            }
494
18.3M
        }
495
37.6M
    }
496
19.5M
}
_ZN5doris10RleEncoderIjE3PutEjm
Line
Count
Source
447
362k
void RleEncoder<T>::Put(T value, size_t run_length) {
448
362k
    DCHECK(bit_width_ == 64 || value < (1LL << bit_width_));
449
450
    // Fast path: if this is a continuation of the current repeated run and
451
    // we've already buffered enough values, just increment repeat_count_
452
362k
    if (current_value_ == value && repeat_count_ >= 8 && run_length > 0) [[likely]] {
453
112
        repeat_count_ += static_cast<int64_t>(run_length);
454
112
        return;
455
112
    }
456
457
    // Handle run_length > 1 more efficiently
458
725k
    while (run_length > 0) {
459
362k
        if (current_value_ == value) [[likely]] {
460
            // Need to buffer values until we reach 8
461
171k
            size_t to_buffer = std::min(run_length, size_t(8 - num_buffered_values_));
462
343k
            for (size_t i = 0; i < to_buffer; ++i) {
463
171k
                buffered_values_[num_buffered_values_++] = value;
464
171k
                ++repeat_count_;
465
171k
            }
466
171k
            run_length -= to_buffer;
467
171k
            if (num_buffered_values_ == 8) {
468
45.2k
                DCHECK_EQ(literal_count_ % 8, 0);
469
45.2k
                FlushBufferedValues(false);
470
                // After flushing, if we still have a repeated run and more values,
471
                // we can add them directly to repeat_count_
472
45.2k
                if (repeat_count_ >= 8 && run_length > 0) {
473
0
                    repeat_count_ += static_cast<int64_t>(run_length);
474
0
                    return;
475
0
                }
476
45.2k
            }
477
191k
        } else {
478
            // Value changed
479
191k
            if (repeat_count_ >= 8) {
480
                // We had a run that was long enough but it has ended.  Flush the
481
                // current repeated run.
482
1
                DCHECK_EQ(literal_count_, 0);
483
1
                FlushRepeatedRun();
484
1
            }
485
191k
            repeat_count_ = 1;
486
191k
            current_value_ = value;
487
488
191k
            buffered_values_[num_buffered_values_++] = value;
489
191k
            --run_length;
490
191k
            if (num_buffered_values_ == 8) {
491
                DCHECK_EQ(literal_count_ % 8, 0);
492
61
                FlushBufferedValues(false);
493
61
            }
494
191k
        }
495
362k
    }
496
362k
}
_ZN5doris10RleEncoderIbE3PutEbm
Line
Count
Source
447
752k
void RleEncoder<T>::Put(T value, size_t run_length) {
448
752k
    DCHECK(bit_width_ == 64 || value < (1LL << bit_width_));
449
450
    // Fast path: if this is a continuation of the current repeated run and
451
    // we've already buffered enough values, just increment repeat_count_
452
752k
    if (current_value_ == value && repeat_count_ >= 8 && run_length > 0) [[likely]] {
453
636k
        repeat_count_ += static_cast<int64_t>(run_length);
454
636k
        return;
455
636k
    }
456
457
    // Handle run_length > 1 more efficiently
458
272k
    while (run_length > 0) {
459
184k
        if (current_value_ == value) [[likely]] {
460
            // Need to buffer values until we reach 8
461
94.3k
            size_t to_buffer = std::min(run_length, size_t(8 - num_buffered_values_));
462
450k
            for (size_t i = 0; i < to_buffer; ++i) {
463
355k
                buffered_values_[num_buffered_values_++] = value;
464
355k
                ++repeat_count_;
465
355k
            }
466
94.3k
            run_length -= to_buffer;
467
94.3k
            if (num_buffered_values_ == 8) {
468
47.5k
                DCHECK_EQ(literal_count_ % 8, 0);
469
47.5k
                FlushBufferedValues(false);
470
                // After flushing, if we still have a repeated run and more values,
471
                // we can add them directly to repeat_count_
472
47.5k
                if (repeat_count_ >= 8 && run_length > 0) {
473
27.5k
                    repeat_count_ += static_cast<int64_t>(run_length);
474
27.5k
                    return;
475
27.5k
                }
476
47.5k
            }
477
94.3k
        } else {
478
            // Value changed
479
89.7k
            if (repeat_count_ >= 8) {
480
                // We had a run that was long enough but it has ended.  Flush the
481
                // current repeated run.
482
24.1k
                DCHECK_EQ(literal_count_, 0);
483
24.1k
                FlushRepeatedRun();
484
24.1k
            }
485
89.7k
            repeat_count_ = 1;
486
89.7k
            current_value_ = value;
487
488
89.7k
            buffered_values_[num_buffered_values_++] = value;
489
89.7k
            --run_length;
490
89.7k
            if (num_buffered_values_ == 8) {
491
                DCHECK_EQ(literal_count_ % 8, 0);
492
7.02k
                FlushBufferedValues(false);
493
7.02k
            }
494
89.7k
        }
495
184k
    }
496
115k
}
_ZN5doris10RleEncoderIhE3PutEhm
Line
Count
Source
447
408
void RleEncoder<T>::Put(T value, size_t run_length) {
448
408
    DCHECK(bit_width_ == 64 || value < (1LL << bit_width_));
449
450
    // Fast path: if this is a continuation of the current repeated run and
451
    // we've already buffered enough values, just increment repeat_count_
452
408
    if (current_value_ == value && repeat_count_ >= 8 && run_length > 0) [[likely]] {
453
0
        repeat_count_ += static_cast<int64_t>(run_length);
454
0
        return;
455
0
    }
456
457
    // Handle run_length > 1 more efficiently
458
816
    while (run_length > 0) {
459
411
        if (current_value_ == value) [[likely]] {
460
            // Need to buffer values until we reach 8
461
8
            size_t to_buffer = std::min(run_length, size_t(8 - num_buffered_values_));
462
34
            for (size_t i = 0; i < to_buffer; ++i) {
463
26
                buffered_values_[num_buffered_values_++] = value;
464
26
                ++repeat_count_;
465
26
            }
466
8
            run_length -= to_buffer;
467
8
            if (num_buffered_values_ == 8) {
468
3
                DCHECK_EQ(literal_count_ % 8, 0);
469
3
                FlushBufferedValues(false);
470
                // After flushing, if we still have a repeated run and more values,
471
                // we can add them directly to repeat_count_
472
3
                if (repeat_count_ >= 8 && run_length > 0) {
473
3
                    repeat_count_ += static_cast<int64_t>(run_length);
474
3
                    return;
475
3
                }
476
3
            }
477
403
        } else {
478
            // Value changed
479
403
            if (repeat_count_ >= 8) {
480
                // We had a run that was long enough but it has ended.  Flush the
481
                // current repeated run.
482
2
                DCHECK_EQ(literal_count_, 0);
483
2
                FlushRepeatedRun();
484
2
            }
485
403
            repeat_count_ = 1;
486
403
            current_value_ = value;
487
488
403
            buffered_values_[num_buffered_values_++] = value;
489
403
            --run_length;
490
403
            if (num_buffered_values_ == 8) {
491
                DCHECK_EQ(literal_count_ % 8, 0);
492
49
                FlushBufferedValues(false);
493
49
            }
494
403
        }
495
411
    }
496
408
}
_ZN5doris10RleEncoderImE3PutEmm
Line
Count
Source
447
19.2M
void RleEncoder<T>::Put(T value, size_t run_length) {
448
19.2M
    DCHECK(bit_width_ == 64 || value < (1LL << bit_width_));
449
450
    // Fast path: if this is a continuation of the current repeated run and
451
    // we've already buffered enough values, just increment repeat_count_
452
19.2M
    if (current_value_ == value && repeat_count_ >= 8 && run_length > 0) [[likely]] {
453
154k
        repeat_count_ += static_cast<int64_t>(run_length);
454
154k
        return;
455
154k
    }
456
457
    // Handle run_length > 1 more efficiently
458
37.2M
    while (run_length > 0) {
459
37.1M
        if (current_value_ == value) [[likely]] {
460
            // Need to buffer values until we reach 8
461
19.0M
            size_t to_buffer = std::min(run_length, size_t(8 - num_buffered_values_));
462
153M
            for (size_t i = 0; i < to_buffer; ++i) {
463
134M
                buffered_values_[num_buffered_values_++] = value;
464
134M
                ++repeat_count_;
465
134M
            }
466
19.0M
            run_length -= to_buffer;
467
19.0M
            if (num_buffered_values_ == 8) {
468
19.0M
                DCHECK_EQ(literal_count_ % 8, 0);
469
19.0M
                FlushBufferedValues(false);
470
                // After flushing, if we still have a repeated run and more values,
471
                // we can add them directly to repeat_count_
472
19.0M
                if (repeat_count_ >= 8 && run_length > 0) {
473
19.0M
                    repeat_count_ += static_cast<int64_t>(run_length);
474
19.0M
                    return;
475
19.0M
                }
476
19.0M
            }
477
19.0M
        } else {
478
            // Value changed
479
18.0M
            if (repeat_count_ >= 8) {
480
                // We had a run that was long enough but it has ended.  Flush the
481
                // current repeated run.
482
8.00M
                DCHECK_EQ(literal_count_, 0);
483
8.00M
                FlushRepeatedRun();
484
8.00M
            }
485
18.0M
            repeat_count_ = 1;
486
18.0M
            current_value_ = value;
487
488
18.0M
            buffered_values_[num_buffered_values_++] = value;
489
18.0M
            --run_length;
490
18.0M
            if (num_buffered_values_ == 8) {
491
                DCHECK_EQ(literal_count_ % 8, 0);
492
9.46k
                FlushBufferedValues(false);
493
9.46k
            }
494
18.0M
        }
495
37.1M
    }
496
19.1M
}
497
498
template <typename T>
499
130k
void RleEncoder<T>::FlushLiteralRun(bool update_indicator_byte) {
500
130k
    if (literal_indicator_byte_idx_ < 0) {
501
        // The literal indicator byte has not been reserved yet, get one now.
502
51.0k
        literal_indicator_byte_idx_ = cast_set<int>(bit_writer_.GetByteIndexAndAdvance(1));
503
51.0k
        DCHECK_GE(literal_indicator_byte_idx_, 0);
504
51.0k
    }
505
506
    // Write all the buffered values as bit packed literals
507
766k
    for (int i = 0; i < num_buffered_values_; ++i) {
508
636k
        bit_writer_.PutValue(buffered_values_[i], bit_width_);
509
636k
    }
510
130k
    num_buffered_values_ = 0;
511
512
130k
    if (update_indicator_byte) {
513
        // At this point we need to write the indicator byte for the literal run.
514
        // We only reserve one byte, to allow for streaming writes of literal values.
515
        // The logic makes sure we flush literal runs often enough to not overrun
516
        // the 1 byte.
517
51.0k
        int num_groups = BitUtil::Ceil(literal_count_, 8);
518
51.0k
        int32_t indicator_value = (num_groups << 1) | 1;
519
51.0k
        DCHECK_EQ(indicator_value & 0xFFFFFF00, 0);
520
51.0k
        bit_writer_.buffer()->data()[literal_indicator_byte_idx_] =
521
51.0k
                cast_set<uint8_t>(indicator_value);
522
51.0k
        literal_indicator_byte_idx_ = -1;
523
51.0k
        literal_count_ = 0;
524
51.0k
    }
525
130k
}
_ZN5doris10RleEncoderIjE15FlushLiteralRunEb
Line
Count
Source
499
90.4k
void RleEncoder<T>::FlushLiteralRun(bool update_indicator_byte) {
500
90.4k
    if (literal_indicator_byte_idx_ < 0) {
501
        // The literal indicator byte has not been reserved yet, get one now.
502
45.1k
        literal_indicator_byte_idx_ = cast_set<int>(bit_writer_.GetByteIndexAndAdvance(1));
503
45.1k
        DCHECK_GE(literal_indicator_byte_idx_, 0);
504
45.1k
    }
505
506
    // Write all the buffered values as bit packed literals
507
452k
    for (int i = 0; i < num_buffered_values_; ++i) {
508
362k
        bit_writer_.PutValue(buffered_values_[i], bit_width_);
509
362k
    }
510
90.4k
    num_buffered_values_ = 0;
511
512
90.4k
    if (update_indicator_byte) {
513
        // At this point we need to write the indicator byte for the literal run.
514
        // We only reserve one byte, to allow for streaming writes of literal values.
515
        // The logic makes sure we flush literal runs often enough to not overrun
516
        // the 1 byte.
517
45.1k
        int num_groups = BitUtil::Ceil(literal_count_, 8);
518
45.1k
        int32_t indicator_value = (num_groups << 1) | 1;
519
        DCHECK_EQ(indicator_value & 0xFFFFFF00, 0);
520
45.1k
        bit_writer_.buffer()->data()[literal_indicator_byte_idx_] =
521
45.1k
                cast_set<uint8_t>(indicator_value);
522
45.1k
        literal_indicator_byte_idx_ = -1;
523
45.1k
        literal_count_ = 0;
524
45.1k
    }
525
90.4k
}
_ZN5doris10RleEncoderIbE15FlushLiteralRunEb
Line
Count
Source
499
27.3k
void RleEncoder<T>::FlushLiteralRun(bool update_indicator_byte) {
500
27.3k
    if (literal_indicator_byte_idx_ < 0) {
501
        // The literal indicator byte has not been reserved yet, get one now.
502
4.69k
        literal_indicator_byte_idx_ = cast_set<int>(bit_writer_.GetByteIndexAndAdvance(1));
503
4.69k
        DCHECK_GE(literal_indicator_byte_idx_, 0);
504
4.69k
    }
505
506
    // Write all the buffered values as bit packed literals
507
211k
    for (int i = 0; i < num_buffered_values_; ++i) {
508
184k
        bit_writer_.PutValue(buffered_values_[i], bit_width_);
509
184k
    }
510
27.3k
    num_buffered_values_ = 0;
511
512
27.3k
    if (update_indicator_byte) {
513
        // At this point we need to write the indicator byte for the literal run.
514
        // We only reserve one byte, to allow for streaming writes of literal values.
515
        // The logic makes sure we flush literal runs often enough to not overrun
516
        // the 1 byte.
517
4.69k
        int num_groups = BitUtil::Ceil(literal_count_, 8);
518
4.69k
        int32_t indicator_value = (num_groups << 1) | 1;
519
        DCHECK_EQ(indicator_value & 0xFFFFFF00, 0);
520
4.69k
        bit_writer_.buffer()->data()[literal_indicator_byte_idx_] =
521
4.69k
                cast_set<uint8_t>(indicator_value);
522
4.69k
        literal_indicator_byte_idx_ = -1;
523
4.69k
        literal_count_ = 0;
524
4.69k
    }
525
27.3k
}
_ZN5doris10RleEncoderIhE15FlushLiteralRunEb
Line
Count
Source
499
53
void RleEncoder<T>::FlushLiteralRun(bool update_indicator_byte) {
500
53
    if (literal_indicator_byte_idx_ < 0) {
501
        // The literal indicator byte has not been reserved yet, get one now.
502
4
        literal_indicator_byte_idx_ = cast_set<int>(bit_writer_.GetByteIndexAndAdvance(1));
503
4
        DCHECK_GE(literal_indicator_byte_idx_, 0);
504
4
    }
505
506
    // Write all the buffered values as bit packed literals
507
458
    for (int i = 0; i < num_buffered_values_; ++i) {
508
405
        bit_writer_.PutValue(buffered_values_[i], bit_width_);
509
405
    }
510
53
    num_buffered_values_ = 0;
511
512
53
    if (update_indicator_byte) {
513
        // At this point we need to write the indicator byte for the literal run.
514
        // We only reserve one byte, to allow for streaming writes of literal values.
515
        // The logic makes sure we flush literal runs often enough to not overrun
516
        // the 1 byte.
517
4
        int num_groups = BitUtil::Ceil(literal_count_, 8);
518
4
        int32_t indicator_value = (num_groups << 1) | 1;
519
        DCHECK_EQ(indicator_value & 0xFFFFFF00, 0);
520
4
        bit_writer_.buffer()->data()[literal_indicator_byte_idx_] =
521
4
                cast_set<uint8_t>(indicator_value);
522
4
        literal_indicator_byte_idx_ = -1;
523
4
        literal_count_ = 0;
524
4
    }
525
53
}
_ZN5doris10RleEncoderImE15FlushLiteralRunEb
Line
Count
Source
499
12.1k
void RleEncoder<T>::FlushLiteralRun(bool update_indicator_byte) {
500
12.1k
    if (literal_indicator_byte_idx_ < 0) {
501
        // The literal indicator byte has not been reserved yet, get one now.
502
1.13k
        literal_indicator_byte_idx_ = cast_set<int>(bit_writer_.GetByteIndexAndAdvance(1));
503
1.13k
        DCHECK_GE(literal_indicator_byte_idx_, 0);
504
1.13k
    }
505
506
    // Write all the buffered values as bit packed literals
507
101k
    for (int i = 0; i < num_buffered_values_; ++i) {
508
89.2k
        bit_writer_.PutValue(buffered_values_[i], bit_width_);
509
89.2k
    }
510
12.1k
    num_buffered_values_ = 0;
511
512
12.1k
    if (update_indicator_byte) {
513
        // At this point we need to write the indicator byte for the literal run.
514
        // We only reserve one byte, to allow for streaming writes of literal values.
515
        // The logic makes sure we flush literal runs often enough to not overrun
516
        // the 1 byte.
517
1.13k
        int num_groups = BitUtil::Ceil(literal_count_, 8);
518
1.13k
        int32_t indicator_value = (num_groups << 1) | 1;
519
        DCHECK_EQ(indicator_value & 0xFFFFFF00, 0);
520
1.13k
        bit_writer_.buffer()->data()[literal_indicator_byte_idx_] =
521
1.13k
                cast_set<uint8_t>(indicator_value);
522
1.13k
        literal_indicator_byte_idx_ = -1;
523
1.13k
        literal_count_ = 0;
524
1.13k
    }
525
12.1k
}
526
527
template <typename T>
528
19.0M
void RleEncoder<T>::FlushRepeatedRun() {
529
19.0M
    DCHECK_GT(repeat_count_, 0);
530
    // A run longer than MAX_VALUES_PER_REPEATED_RUN cannot be described by a
531
    // single indicator, so emit it as several back-to-back repeated runs of the
532
    // same value. Decoders stitch those back together transparently
533
    // (RleDecoder::GetNextRun merges adjacent runs carrying the same value), so
534
    // splitting is invisible to readers.
535
38.0M
    while (repeat_count_ > 0) {
536
19.0M
        const int64_t run_length = std::min(repeat_count_, MAX_VALUES_PER_REPEATED_RUN);
537
        // The lsb of 0 indicates this is a repeated run
538
19.0M
        bit_writer_.PutVlqInt(static_cast<uint32_t>(run_length) << 1);
539
19.0M
        bit_writer_.PutAligned(current_value_, BitUtil::Ceil(bit_width_, 8));
540
19.0M
        repeat_count_ -= run_length;
541
19.0M
    }
542
19.0M
    num_buffered_values_ = 0;
543
    // The loop above drains repeat_count_; assign it anyway so the postcondition
544
    // holds even if it somehow entered non-positive.
545
19.0M
    repeat_count_ = 0;
546
19.0M
}
_ZN5doris10RleEncoderIjE16FlushRepeatedRunEv
Line
Count
Source
528
72
void RleEncoder<T>::FlushRepeatedRun() {
529
72
    DCHECK_GT(repeat_count_, 0);
530
    // A run longer than MAX_VALUES_PER_REPEATED_RUN cannot be described by a
531
    // single indicator, so emit it as several back-to-back repeated runs of the
532
    // same value. Decoders stitch those back together transparently
533
    // (RleDecoder::GetNextRun merges adjacent runs carrying the same value), so
534
    // splitting is invisible to readers.
535
144
    while (repeat_count_ > 0) {
536
72
        const int64_t run_length = std::min(repeat_count_, MAX_VALUES_PER_REPEATED_RUN);
537
        // The lsb of 0 indicates this is a repeated run
538
72
        bit_writer_.PutVlqInt(static_cast<uint32_t>(run_length) << 1);
539
72
        bit_writer_.PutAligned(current_value_, BitUtil::Ceil(bit_width_, 8));
540
72
        repeat_count_ -= run_length;
541
72
    }
542
72
    num_buffered_values_ = 0;
543
    // The loop above drains repeat_count_; assign it anyway so the postcondition
544
    // holds even if it somehow entered non-positive.
545
72
    repeat_count_ = 0;
546
72
}
_ZN5doris10RleEncoderIbE16FlushRepeatedRunEv
Line
Count
Source
528
24.5k
void RleEncoder<T>::FlushRepeatedRun() {
529
24.5k
    DCHECK_GT(repeat_count_, 0);
530
    // A run longer than MAX_VALUES_PER_REPEATED_RUN cannot be described by a
531
    // single indicator, so emit it as several back-to-back repeated runs of the
532
    // same value. Decoders stitch those back together transparently
533
    // (RleDecoder::GetNextRun merges adjacent runs carrying the same value), so
534
    // splitting is invisible to readers.
535
49.0k
    while (repeat_count_ > 0) {
536
24.5k
        const int64_t run_length = std::min(repeat_count_, MAX_VALUES_PER_REPEATED_RUN);
537
        // The lsb of 0 indicates this is a repeated run
538
24.5k
        bit_writer_.PutVlqInt(static_cast<uint32_t>(run_length) << 1);
539
24.5k
        bit_writer_.PutAligned(current_value_, BitUtil::Ceil(bit_width_, 8));
540
24.5k
        repeat_count_ -= run_length;
541
24.5k
    }
542
24.5k
    num_buffered_values_ = 0;
543
    // The loop above drains repeat_count_; assign it anyway so the postcondition
544
    // holds even if it somehow entered non-positive.
545
24.5k
    repeat_count_ = 0;
546
24.5k
}
_ZN5doris10RleEncoderIhE16FlushRepeatedRunEv
Line
Count
Source
528
3
void RleEncoder<T>::FlushRepeatedRun() {
529
3
    DCHECK_GT(repeat_count_, 0);
530
    // A run longer than MAX_VALUES_PER_REPEATED_RUN cannot be described by a
531
    // single indicator, so emit it as several back-to-back repeated runs of the
532
    // same value. Decoders stitch those back together transparently
533
    // (RleDecoder::GetNextRun merges adjacent runs carrying the same value), so
534
    // splitting is invisible to readers.
535
6
    while (repeat_count_ > 0) {
536
3
        const int64_t run_length = std::min(repeat_count_, MAX_VALUES_PER_REPEATED_RUN);
537
        // The lsb of 0 indicates this is a repeated run
538
3
        bit_writer_.PutVlqInt(static_cast<uint32_t>(run_length) << 1);
539
3
        bit_writer_.PutAligned(current_value_, BitUtil::Ceil(bit_width_, 8));
540
3
        repeat_count_ -= run_length;
541
3
    }
542
3
    num_buffered_values_ = 0;
543
    // The loop above drains repeat_count_; assign it anyway so the postcondition
544
    // holds even if it somehow entered non-positive.
545
3
    repeat_count_ = 0;
546
3
}
_ZN5doris10RleEncoderImE16FlushRepeatedRunEv
Line
Count
Source
528
19.0M
void RleEncoder<T>::FlushRepeatedRun() {
529
19.0M
    DCHECK_GT(repeat_count_, 0);
530
    // A run longer than MAX_VALUES_PER_REPEATED_RUN cannot be described by a
531
    // single indicator, so emit it as several back-to-back repeated runs of the
532
    // same value. Decoders stitch those back together transparently
533
    // (RleDecoder::GetNextRun merges adjacent runs carrying the same value), so
534
    // splitting is invisible to readers.
535
38.0M
    while (repeat_count_ > 0) {
536
19.0M
        const int64_t run_length = std::min(repeat_count_, MAX_VALUES_PER_REPEATED_RUN);
537
        // The lsb of 0 indicates this is a repeated run
538
19.0M
        bit_writer_.PutVlqInt(static_cast<uint32_t>(run_length) << 1);
539
19.0M
        bit_writer_.PutAligned(current_value_, BitUtil::Ceil(bit_width_, 8));
540
19.0M
        repeat_count_ -= run_length;
541
19.0M
    }
542
19.0M
    num_buffered_values_ = 0;
543
    // The loop above drains repeat_count_; assign it anyway so the postcondition
544
    // holds even if it somehow entered non-positive.
545
19.0M
    repeat_count_ = 0;
546
19.0M
}
547
548
// Flush the values that have been buffered.  At this point we decide whether
549
// we need to switch between the run types or continue the current one.
550
template <typename T>
551
19.1M
void RleEncoder<T>::FlushBufferedValues(bool done) {
552
19.1M
    if (repeat_count_ >= 8) {
553
        // Clear the buffered values.  They are part of the repeated run now and we
554
        // don't want to flush them out as literals.
555
19.0M
        num_buffered_values_ = 0;
556
19.0M
        if (literal_count_ != 0) {
557
            // There was a current literal run.  All the values in it have been flushed
558
            // but we still need to update the indicator byte.
559
4.82k
            DCHECK_EQ(literal_count_ % 8, 0);
560
4.82k
            DCHECK_EQ(repeat_count_, 8);
561
4.82k
            FlushLiteralRun(true);
562
4.82k
        }
563
19.0M
        DCHECK_EQ(literal_count_, 0);
564
19.0M
        return;
565
19.0M
    }
566
567
79.1k
    literal_count_ += num_buffered_values_;
568
79.1k
    int num_groups = BitUtil::Ceil(literal_count_, 8);
569
79.1k
    if (num_groups + 1 >= (1 << 6)) {
570
        // We need to start a new literal run because the indicator byte we've reserved
571
        // cannot store more values.
572
170
        DCHECK_GE(literal_indicator_byte_idx_, 0);
573
170
        FlushLiteralRun(true);
574
78.9k
    } else {
575
78.9k
        FlushLiteralRun(done);
576
78.9k
    }
577
79.1k
    repeat_count_ = 0;
578
79.1k
}
_ZN5doris10RleEncoderIjE19FlushBufferedValuesEb
Line
Count
Source
551
45.3k
void RleEncoder<T>::FlushBufferedValues(bool done) {
552
45.3k
    if (repeat_count_ >= 8) {
553
        // Clear the buffered values.  They are part of the repeated run now and we
554
        // don't want to flush them out as literals.
555
72
        num_buffered_values_ = 0;
556
72
        if (literal_count_ != 0) {
557
            // There was a current literal run.  All the values in it have been flushed
558
            // but we still need to update the indicator byte.
559
0
            DCHECK_EQ(literal_count_ % 8, 0);
560
0
            DCHECK_EQ(repeat_count_, 8);
561
0
            FlushLiteralRun(true);
562
0
        }
563
72
        DCHECK_EQ(literal_count_, 0);
564
72
        return;
565
72
    }
566
567
45.2k
    literal_count_ += num_buffered_values_;
568
45.2k
    int num_groups = BitUtil::Ceil(literal_count_, 8);
569
45.2k
    if (num_groups + 1 >= (1 << 6)) {
570
        // We need to start a new literal run because the indicator byte we've reserved
571
        // cannot store more values.
572
0
        DCHECK_GE(literal_indicator_byte_idx_, 0);
573
0
        FlushLiteralRun(true);
574
45.2k
    } else {
575
45.2k
        FlushLiteralRun(done);
576
45.2k
    }
577
45.2k
    repeat_count_ = 0;
578
45.2k
}
_ZN5doris10RleEncoderIbE19FlushBufferedValuesEb
Line
Count
Source
551
54.5k
void RleEncoder<T>::FlushBufferedValues(bool done) {
552
54.5k
    if (repeat_count_ >= 8) {
553
        // Clear the buffered values.  They are part of the repeated run now and we
554
        // don't want to flush them out as literals.
555
31.8k
        num_buffered_values_ = 0;
556
31.8k
        if (literal_count_ != 0) {
557
            // There was a current literal run.  All the values in it have been flushed
558
            // but we still need to update the indicator byte.
559
3.95k
            DCHECK_EQ(literal_count_ % 8, 0);
560
3.95k
            DCHECK_EQ(repeat_count_, 8);
561
3.95k
            FlushLiteralRun(true);
562
3.95k
        }
563
31.8k
        DCHECK_EQ(literal_count_, 0);
564
31.8k
        return;
565
31.8k
    }
566
567
22.7k
    literal_count_ += num_buffered_values_;
568
22.7k
    int num_groups = BitUtil::Ceil(literal_count_, 8);
569
22.7k
    if (num_groups + 1 >= (1 << 6)) {
570
        // We need to start a new literal run because the indicator byte we've reserved
571
        // cannot store more values.
572
42
        DCHECK_GE(literal_indicator_byte_idx_, 0);
573
42
        FlushLiteralRun(true);
574
22.6k
    } else {
575
22.6k
        FlushLiteralRun(done);
576
22.6k
    }
577
22.7k
    repeat_count_ = 0;
578
22.7k
}
_ZN5doris10RleEncoderIhE19FlushBufferedValuesEb
Line
Count
Source
551
52
void RleEncoder<T>::FlushBufferedValues(bool done) {
552
52
    if (repeat_count_ >= 8) {
553
        // Clear the buffered values.  They are part of the repeated run now and we
554
        // don't want to flush them out as literals.
555
3
        num_buffered_values_ = 0;
556
3
        if (literal_count_ != 0) {
557
            // There was a current literal run.  All the values in it have been flushed
558
            // but we still need to update the indicator byte.
559
0
            DCHECK_EQ(literal_count_ % 8, 0);
560
0
            DCHECK_EQ(repeat_count_, 8);
561
0
            FlushLiteralRun(true);
562
0
        }
563
3
        DCHECK_EQ(literal_count_, 0);
564
3
        return;
565
3
    }
566
567
49
    literal_count_ += num_buffered_values_;
568
49
    int num_groups = BitUtil::Ceil(literal_count_, 8);
569
49
    if (num_groups + 1 >= (1 << 6)) {
570
        // We need to start a new literal run because the indicator byte we've reserved
571
        // cannot store more values.
572
0
        DCHECK_GE(literal_indicator_byte_idx_, 0);
573
0
        FlushLiteralRun(true);
574
49
    } else {
575
49
        FlushLiteralRun(done);
576
49
    }
577
49
    repeat_count_ = 0;
578
49
}
_ZN5doris10RleEncoderImE19FlushBufferedValuesEb
Line
Count
Source
551
19.0M
void RleEncoder<T>::FlushBufferedValues(bool done) {
552
19.0M
    if (repeat_count_ >= 8) {
553
        // Clear the buffered values.  They are part of the repeated run now and we
554
        // don't want to flush them out as literals.
555
19.0M
        num_buffered_values_ = 0;
556
19.0M
        if (literal_count_ != 0) {
557
            // There was a current literal run.  All the values in it have been flushed
558
            // but we still need to update the indicator byte.
559
869
            DCHECK_EQ(literal_count_ % 8, 0);
560
869
            DCHECK_EQ(repeat_count_, 8);
561
869
            FlushLiteralRun(true);
562
869
        }
563
19.0M
        DCHECK_EQ(literal_count_, 0);
564
19.0M
        return;
565
19.0M
    }
566
567
11.1k
    literal_count_ += num_buffered_values_;
568
11.1k
    int num_groups = BitUtil::Ceil(literal_count_, 8);
569
11.1k
    if (num_groups + 1 >= (1 << 6)) {
570
        // We need to start a new literal run because the indicator byte we've reserved
571
        // cannot store more values.
572
128
        DCHECK_GE(literal_indicator_byte_idx_, 0);
573
128
        FlushLiteralRun(true);
574
10.9k
    } else {
575
10.9k
        FlushLiteralRun(done);
576
10.9k
    }
577
11.1k
    repeat_count_ = 0;
578
11.1k
}
579
580
template <typename T>
581
8
void RleEncoder<T>::Reserve(int num_bytes, uint8_t val) {
582
40
    for (int i = 0; i < num_bytes; ++i) {
583
32
        bit_writer_.PutValue(val, 8);
584
32
    }
585
8
}
586
587
template <typename T>
588
11.0M
int RleEncoder<T>::Flush() {
589
11.0M
    if (literal_count_ > 0 || repeat_count_ > 0 || num_buffered_values_ > 0) {
590
11.0M
        bool all_repeat = literal_count_ == 0 &&
591
11.0M
                          (repeat_count_ == num_buffered_values_ || num_buffered_values_ == 0);
592
        // There is something pending, figure out if it's a repeated or literal run
593
11.0M
        if (repeat_count_ > 0 && all_repeat) {
594
11.0M
            FlushRepeatedRun();
595
11.0M
        } else {
596
46.0k
            literal_count_ += num_buffered_values_;
597
46.0k
            FlushLiteralRun(true);
598
46.0k
            repeat_count_ = 0;
599
46.0k
        }
600
11.0M
    }
601
11.0M
    bit_writer_.Flush();
602
11.0M
    DCHECK_EQ(num_buffered_values_, 0);
603
11.0M
    DCHECK_EQ(literal_count_, 0);
604
11.0M
    DCHECK_EQ(repeat_count_, 0);
605
11.0M
    return bit_writer_.bytes_written();
606
11.0M
}
_ZN5doris10RleEncoderIjE5FlushEv
Line
Count
Source
588
45.2k
int RleEncoder<T>::Flush() {
589
45.2k
    if (literal_count_ > 0 || repeat_count_ > 0 || num_buffered_values_ > 0) {
590
45.2k
        bool all_repeat = literal_count_ == 0 &&
591
45.2k
                          (repeat_count_ == num_buffered_values_ || num_buffered_values_ == 0);
592
        // There is something pending, figure out if it's a repeated or literal run
593
45.2k
        if (repeat_count_ > 0 && all_repeat) {
594
71
            FlushRepeatedRun();
595
45.1k
        } else {
596
45.1k
            literal_count_ += num_buffered_values_;
597
45.1k
            FlushLiteralRun(true);
598
45.1k
            repeat_count_ = 0;
599
45.1k
        }
600
45.2k
    }
601
45.2k
    bit_writer_.Flush();
602
45.2k
    DCHECK_EQ(num_buffered_values_, 0);
603
45.2k
    DCHECK_EQ(literal_count_, 0);
604
    DCHECK_EQ(repeat_count_, 0);
605
45.2k
    return bit_writer_.bytes_written();
606
45.2k
}
_ZN5doris10RleEncoderIbE5FlushEv
Line
Count
Source
588
1.10k
int RleEncoder<T>::Flush() {
589
1.10k
    if (literal_count_ > 0 || repeat_count_ > 0 || num_buffered_values_ > 0) {
590
1.09k
        bool all_repeat = literal_count_ == 0 &&
591
1.09k
                          (repeat_count_ == num_buffered_values_ || num_buffered_values_ == 0);
592
        // There is something pending, figure out if it's a repeated or literal run
593
1.09k
        if (repeat_count_ > 0 && all_repeat) {
594
400
            FlushRepeatedRun();
595
698
        } else {
596
698
            literal_count_ += num_buffered_values_;
597
698
            FlushLiteralRun(true);
598
698
            repeat_count_ = 0;
599
698
        }
600
1.09k
    }
601
1.10k
    bit_writer_.Flush();
602
1.10k
    DCHECK_EQ(num_buffered_values_, 0);
603
1.10k
    DCHECK_EQ(literal_count_, 0);
604
    DCHECK_EQ(repeat_count_, 0);
605
1.10k
    return bit_writer_.bytes_written();
606
1.10k
}
_ZN5doris10RleEncoderIhE5FlushEv
Line
Count
Source
588
5
int RleEncoder<T>::Flush() {
589
5
    if (literal_count_ > 0 || repeat_count_ > 0 || num_buffered_values_ > 0) {
590
5
        bool all_repeat = literal_count_ == 0 &&
591
5
                          (repeat_count_ == num_buffered_values_ || num_buffered_values_ == 0);
592
        // There is something pending, figure out if it's a repeated or literal run
593
5
        if (repeat_count_ > 0 && all_repeat) {
594
1
            FlushRepeatedRun();
595
4
        } else {
596
4
            literal_count_ += num_buffered_values_;
597
4
            FlushLiteralRun(true);
598
4
            repeat_count_ = 0;
599
4
        }
600
5
    }
601
5
    bit_writer_.Flush();
602
5
    DCHECK_EQ(num_buffered_values_, 0);
603
5
    DCHECK_EQ(literal_count_, 0);
604
    DCHECK_EQ(repeat_count_, 0);
605
5
    return bit_writer_.bytes_written();
606
5
}
_ZN5doris10RleEncoderImE5FlushEv
Line
Count
Source
588
11.0M
int RleEncoder<T>::Flush() {
589
11.0M
    if (literal_count_ > 0 || repeat_count_ > 0 || num_buffered_values_ > 0) {
590
11.0M
        bool all_repeat = literal_count_ == 0 &&
591
11.0M
                          (repeat_count_ == num_buffered_values_ || num_buffered_values_ == 0);
592
        // There is something pending, figure out if it's a repeated or literal run
593
11.0M
        if (repeat_count_ > 0 && all_repeat) {
594
11.0M
            FlushRepeatedRun();
595
11.0M
        } else {
596
139
            literal_count_ += num_buffered_values_;
597
139
            FlushLiteralRun(true);
598
139
            repeat_count_ = 0;
599
139
        }
600
11.0M
    }
601
11.0M
    bit_writer_.Flush();
602
11.0M
    DCHECK_EQ(num_buffered_values_, 0);
603
11.0M
    DCHECK_EQ(literal_count_, 0);
604
    DCHECK_EQ(repeat_count_, 0);
605
11.0M
    return bit_writer_.bytes_written();
606
11.0M
}
607
608
template <typename T>
609
11.0M
void RleEncoder<T>::Clear() {
610
11.0M
    current_value_ = 0;
611
11.0M
    repeat_count_ = 0;
612
11.0M
    num_buffered_values_ = 0;
613
11.0M
    literal_count_ = 0;
614
11.0M
    literal_indicator_byte_idx_ = -1;
615
11.0M
    bit_writer_.Clear();
616
11.0M
}
_ZN5doris10RleEncoderIjE5ClearEv
Line
Count
Source
609
45.2k
void RleEncoder<T>::Clear() {
610
45.2k
    current_value_ = 0;
611
45.2k
    repeat_count_ = 0;
612
45.2k
    num_buffered_values_ = 0;
613
45.2k
    literal_count_ = 0;
614
45.2k
    literal_indicator_byte_idx_ = -1;
615
45.2k
    bit_writer_.Clear();
616
45.2k
}
_ZN5doris10RleEncoderIbE5ClearEv
Line
Count
Source
609
16.7k
void RleEncoder<T>::Clear() {
610
16.7k
    current_value_ = 0;
611
16.7k
    repeat_count_ = 0;
612
16.7k
    num_buffered_values_ = 0;
613
16.7k
    literal_count_ = 0;
614
16.7k
    literal_indicator_byte_idx_ = -1;
615
16.7k
    bit_writer_.Clear();
616
16.7k
}
_ZN5doris10RleEncoderIhE5ClearEv
Line
Count
Source
609
13
void RleEncoder<T>::Clear() {
610
13
    current_value_ = 0;
611
13
    repeat_count_ = 0;
612
13
    num_buffered_values_ = 0;
613
13
    literal_count_ = 0;
614
13
    literal_indicator_byte_idx_ = -1;
615
13
    bit_writer_.Clear();
616
13
}
_ZN5doris10RleEncoderImE5ClearEv
Line
Count
Source
609
11.0M
void RleEncoder<T>::Clear() {
610
11.0M
    current_value_ = 0;
611
11.0M
    repeat_count_ = 0;
612
11.0M
    num_buffered_values_ = 0;
613
11.0M
    literal_count_ = 0;
614
11.0M
    literal_indicator_byte_idx_ = -1;
615
11.0M
    bit_writer_.Clear();
616
11.0M
}
617
618
// Copy from https://github.com/apache/impala/blob/master/be/src/util/rle-encoding.h
619
// Utility classes to do run length encoding (RLE) for fixed bit width values.  If runs
620
// are sufficiently long, RLE is used, otherwise, the values are just bit-packed
621
// (literal encoding).
622
//
623
// For both types of runs, there is a byte-aligned indicator which encodes the length
624
// of the run and the type of the run.
625
//
626
// This encoding has the benefit that when there aren't any long enough runs, values
627
// are always decoded at fixed (can be precomputed) bit offsets OR both the value and
628
// the run length are byte aligned. This allows for very efficient decoding
629
// implementations.
630
// The encoding is:
631
//    encoded-block := run*
632
//    run := literal-run | repeated-run
633
//    literal-run := literal-indicator < literal bytes >
634
//    repeated-run := repeated-indicator < repeated value. padded to byte boundary >
635
//    literal-indicator := varint_encode( number_of_groups << 1 | 1)
636
//    repeated-indicator := varint_encode( number_of_repetitions << 1 )
637
//
638
// Each run is preceded by a varint. The varint's least significant bit is
639
// used to indicate whether the run is a literal run or a repeated run. The rest
640
// of the varint is used to determine the length of the run (eg how many times the
641
// value repeats).
642
//
643
// In the case of literal runs, the run length is always a multiple of 8 (i.e. encode
644
// in groups of 8), so that no matter the bit-width of the value, the sequence will end
645
// on a byte boundary without padding.
646
// Given that we know it is a multiple of 8, we store the number of 8-groups rather than
647
// the actual number of encoded ints. (This means that the total number of encoded values
648
// can not be determined from the encoded data, since the number of values in the last
649
// group may not be a multiple of 8). For the last group of literal runs, we pad
650
// the group to 8 with zeros. This allows for 8 at a time decoding on the read side
651
// without the need for additional checks.
652
//
653
// There is a break-even point when it is more storage efficient to do run length
654
// encoding.  For 1 bit-width values, that point is 8 values.  They require 2 bytes
655
// for both the repeated encoding or the literal encoding.  This value can always
656
// be computed based on the bit-width.
657
// TODO: For 1 bit-width values it can be optimal to use 16 or 24 values, but more
658
// investigation is needed to do this efficiently, see the reverted IMPALA-6658.
659
// TODO: think about how to use this for strings.  The bit packing isn't quite the same.
660
//
661
// Examples with bit-width 1 (eg encoding booleans):
662
// ----------------------------------------
663
// 100 1s followed by 100 0s:
664
// <varint(100 << 1)> <1, padded to 1 byte> <varint(100 << 1)> <0, padded to 1 byte>
665
//  - (total 4 bytes)
666
//
667
// alternating 1s and 0s (200 total):
668
// 200 ints = 25 groups of 8
669
// <varint((25 << 1) | 1)> <25 bytes of values, bitpacked>
670
// (total 26 bytes, 1 byte overhead)
671
672
// RLE decoder with a batch-oriented interface that enables fast decoding.
673
// Users of this class must first initialize the class to point to a buffer of
674
// RLE-encoded data, passed into the constructor or Reset(). The provided
675
// bit_width must be at most min(sizeof(T) * 8, BatchedBitReader::MAX_BITWIDTH).
676
// Then they can decode data by checking NextNumRepeats()/NextNumLiterals() to
677
// see if the next run is a repeated or literal run, then calling
678
// GetRepeatedValue() or GetLiteralValues() respectively to read the values.
679
//
680
// End-of-input is signalled by NextNumRepeats() == NextNumLiterals() == 0.
681
// Other decoding errors are signalled by functions returning false. If an
682
// error is encountered then it is not valid to read any more data until
683
// Reset() is called.
684
685
//bit-packed-run-len and rle-run-len must be in the range [1, 2^31 - 1].
686
// This means that a Parquet implementation can always store the run length in a signed 32-bit integer.
687
template <typename T>
688
class RleBatchDecoder {
689
public:
690
188k
    RleBatchDecoder(uint8_t* buffer, int buffer_len, int bit_width) {
691
188k
        Reset(buffer, buffer_len, bit_width);
692
188k
    }
_ZN5doris15RleBatchDecoderIjEC2EPhii
Line
Count
Source
690
48.1k
    RleBatchDecoder(uint8_t* buffer, int buffer_len, int bit_width) {
691
48.1k
        Reset(buffer, buffer_len, bit_width);
692
48.1k
    }
_ZN5doris15RleBatchDecoderIhEC2EPhii
Line
Count
Source
690
6
    RleBatchDecoder(uint8_t* buffer, int buffer_len, int bit_width) {
691
6
        Reset(buffer, buffer_len, bit_width);
692
6
    }
_ZN5doris15RleBatchDecoderItEC2EPhii
Line
Count
Source
690
140k
    RleBatchDecoder(uint8_t* buffer, int buffer_len, int bit_width) {
691
140k
        Reset(buffer, buffer_len, bit_width);
692
140k
    }
693
694
71.9k
    RleBatchDecoder() = default;
_ZN5doris15RleBatchDecoderItEC2Ev
Line
Count
Source
694
71.9k
    RleBatchDecoder() = default;
_ZN5doris15RleBatchDecoderIhEC2Ev
Line
Count
Source
694
8
    RleBatchDecoder() = default;
695
696
    // Reset the decoder to read from a new buffer.
697
    void Reset(uint8_t* buffer, int buffer_len, int bit_width);
698
699
    // Return the size of the current repeated run. Returns zero if the current run is
700
    // a literal run or if no more runs can be read from the input.
701
    int32_t NextNumRepeats();
702
703
    // Get the value of the current repeated run and consume the given number of repeats.
704
    // Only valid to call when NextNumRepeats() > 0. The given number of repeats cannot
705
    // be greater than the remaining number of repeats in the run. 'num_repeats_to_consume'
706
    // can be set to 0 to peek at the value without consuming repeats.
707
    T GetRepeatedValue(int32_t num_repeats_to_consume);
708
709
    // Return the size of the current literal run. Returns zero if the current run is
710
    // a repeated run or if no more runs can be read from the input.
711
    int32_t NextNumLiterals();
712
713
    // Consume 'num_literals_to_consume' literals from the current literal run,
714
    // copying the values to 'values'. 'num_literals_to_consume' must be <=
715
    // NextNumLiterals(). Returns true if the requested number of literals were
716
    // successfully read or false if an error was encountered, e.g. the input was
717
    // truncated.
718
    bool GetLiteralValues(int32_t num_literals_to_consume, T* values) WARN_UNUSED_RESULT;
719
720
    // Consume 'num_values_to_consume' values and copy them to 'values'.
721
    // Returns the number of consumed values or 0 if an error occurred.
722
    uint32_t GetBatch(T* values, uint32_t batch_num);
723
724
private:
725
    // Called when both 'literal_count_' and 'repeat_count_' have been exhausted.
726
    // Sets either 'literal_count_' or 'repeat_count_' to the size of the next literal
727
    // or repeated run, or leaves both at 0 if no more values can be read (either because
728
    // the end of the input was reached or an error was encountered decoding).
729
    void NextCounts();
730
731
    /// Fill the literal buffer. Invalid to call if there are already buffered literals.
732
    /// Return false if the input was truncated. This does not advance 'literal_count_'.
733
    bool FillLiteralBuffer() WARN_UNUSED_RESULT;
734
735
558k
    bool HaveBufferedLiterals() const { return literal_buffer_pos_ < num_buffered_literals_; }
_ZNK5doris15RleBatchDecoderIjE20HaveBufferedLiteralsEv
Line
Count
Source
735
82.0k
    bool HaveBufferedLiterals() const { return literal_buffer_pos_ < num_buffered_literals_; }
_ZNK5doris15RleBatchDecoderIhE20HaveBufferedLiteralsEv
Line
Count
Source
735
9
    bool HaveBufferedLiterals() const { return literal_buffer_pos_ < num_buffered_literals_; }
_ZNK5doris15RleBatchDecoderItE20HaveBufferedLiteralsEv
Line
Count
Source
735
476k
    bool HaveBufferedLiterals() const { return literal_buffer_pos_ < num_buffered_literals_; }
736
737
    /// Output buffered literals, advancing 'literal_buffer_pos_' and decrementing
738
    /// 'literal_count_'. Returns the number of literals outputted.
739
    int32_t OutputBufferedLiterals(int32_t max_to_output, T* values);
740
741
    BatchedBitReader bit_reader_;
742
743
    // Number of bits needed to encode the value. Must be between 0 and 64 after
744
    // the decoder is initialized with a buffer. -1 indicates the decoder was not
745
    // initialized.
746
    int bit_width_ = -1;
747
748
    // If a repeated run, the number of repeats remaining in the current run to be read.
749
    // If the current run is a literal run, this is 0.
750
    int32_t repeat_count_ = 0;
751
752
    // If a literal run, the number of literals remaining in the current run to be read.
753
    // If the current run is a repeated run, this is 0.
754
    int32_t literal_count_ = 0;
755
756
    // If a repeated run, the current repeated value.
757
    T repeated_value_;
758
759
    // Size of buffer for literal values. Large enough to decode a full batch of 32
760
    // literals. The buffer is needed to allow clients to read in batches that are not
761
    // multiples of 32.
762
    static constexpr int LITERAL_BUFFER_LEN = 32;
763
764
    // Buffer containing 'num_buffered_literals_' values. 'literal_buffer_pos_' is the
765
    // position of the next literal to be read from the buffer.
766
    T literal_buffer_[LITERAL_BUFFER_LEN];
767
    int num_buffered_literals_ = 0;
768
    int literal_buffer_pos_ = 0;
769
};
770
771
template <typename T>
772
558k
int32_t RleBatchDecoder<T>::OutputBufferedLiterals(int32_t max_to_output, T* values) {
773
558k
    int32_t num_to_output =
774
558k
            std::min<int32_t>(max_to_output, num_buffered_literals_ - literal_buffer_pos_);
775
558k
    memcpy(values, &literal_buffer_[literal_buffer_pos_], sizeof(T) * num_to_output);
776
558k
    literal_buffer_pos_ += num_to_output;
777
558k
    literal_count_ -= num_to_output;
778
558k
    return num_to_output;
779
558k
}
_ZN5doris15RleBatchDecoderIjE22OutputBufferedLiteralsEiPj
Line
Count
Source
772
82.4k
int32_t RleBatchDecoder<T>::OutputBufferedLiterals(int32_t max_to_output, T* values) {
773
82.4k
    int32_t num_to_output =
774
82.4k
            std::min<int32_t>(max_to_output, num_buffered_literals_ - literal_buffer_pos_);
775
82.4k
    memcpy(values, &literal_buffer_[literal_buffer_pos_], sizeof(T) * num_to_output);
776
82.4k
    literal_buffer_pos_ += num_to_output;
777
82.4k
    literal_count_ -= num_to_output;
778
82.4k
    return num_to_output;
779
82.4k
}
_ZN5doris15RleBatchDecoderIhE22OutputBufferedLiteralsEiPh
Line
Count
Source
772
6
int32_t RleBatchDecoder<T>::OutputBufferedLiterals(int32_t max_to_output, T* values) {
773
6
    int32_t num_to_output =
774
6
            std::min<int32_t>(max_to_output, num_buffered_literals_ - literal_buffer_pos_);
775
6
    memcpy(values, &literal_buffer_[literal_buffer_pos_], sizeof(T) * num_to_output);
776
6
    literal_buffer_pos_ += num_to_output;
777
6
    literal_count_ -= num_to_output;
778
6
    return num_to_output;
779
6
}
_ZN5doris15RleBatchDecoderItE22OutputBufferedLiteralsEiPt
Line
Count
Source
772
476k
int32_t RleBatchDecoder<T>::OutputBufferedLiterals(int32_t max_to_output, T* values) {
773
476k
    int32_t num_to_output =
774
476k
            std::min<int32_t>(max_to_output, num_buffered_literals_ - literal_buffer_pos_);
775
476k
    memcpy(values, &literal_buffer_[literal_buffer_pos_], sizeof(T) * num_to_output);
776
476k
    literal_buffer_pos_ += num_to_output;
777
476k
    literal_count_ -= num_to_output;
778
476k
    return num_to_output;
779
476k
}
780
781
template <typename T>
782
188k
void RleBatchDecoder<T>::Reset(uint8_t* buffer, int buffer_len, int bit_width) {
783
188k
    bit_reader_.Reset(buffer, buffer_len);
784
188k
    bit_width_ = bit_width;
785
188k
    repeat_count_ = 0;
786
188k
    literal_count_ = 0;
787
188k
    num_buffered_literals_ = 0;
788
188k
    literal_buffer_pos_ = 0;
789
188k
}
_ZN5doris15RleBatchDecoderIjE5ResetEPhii
Line
Count
Source
782
48.1k
void RleBatchDecoder<T>::Reset(uint8_t* buffer, int buffer_len, int bit_width) {
783
48.1k
    bit_reader_.Reset(buffer, buffer_len);
784
48.1k
    bit_width_ = bit_width;
785
48.1k
    repeat_count_ = 0;
786
48.1k
    literal_count_ = 0;
787
48.1k
    num_buffered_literals_ = 0;
788
48.1k
    literal_buffer_pos_ = 0;
789
48.1k
}
_ZN5doris15RleBatchDecoderIhE5ResetEPhii
Line
Count
Source
782
6
void RleBatchDecoder<T>::Reset(uint8_t* buffer, int buffer_len, int bit_width) {
783
6
    bit_reader_.Reset(buffer, buffer_len);
784
6
    bit_width_ = bit_width;
785
6
    repeat_count_ = 0;
786
6
    literal_count_ = 0;
787
6
    num_buffered_literals_ = 0;
788
6
    literal_buffer_pos_ = 0;
789
6
}
_ZN5doris15RleBatchDecoderItE5ResetEPhii
Line
Count
Source
782
140k
void RleBatchDecoder<T>::Reset(uint8_t* buffer, int buffer_len, int bit_width) {
783
140k
    bit_reader_.Reset(buffer, buffer_len);
784
140k
    bit_width_ = bit_width;
785
140k
    repeat_count_ = 0;
786
140k
    literal_count_ = 0;
787
140k
    num_buffered_literals_ = 0;
788
140k
    literal_buffer_pos_ = 0;
789
140k
}
790
791
template <typename T>
792
560k
int32_t RleBatchDecoder<T>::NextNumRepeats() {
793
560k
    if (repeat_count_ > 0) return repeat_count_;
794
558k
    if (literal_count_ == 0) NextCounts();
795
558k
    return repeat_count_;
796
560k
}
_ZN5doris15RleBatchDecoderIjE14NextNumRepeatsEv
Line
Count
Source
792
82.7k
int32_t RleBatchDecoder<T>::NextNumRepeats() {
793
82.7k
    if (repeat_count_ > 0) return repeat_count_;
794
82.3k
    if (literal_count_ == 0) NextCounts();
795
82.3k
    return repeat_count_;
796
82.7k
}
_ZN5doris15RleBatchDecoderIhE14NextNumRepeatsEv
Line
Count
Source
792
265
int32_t RleBatchDecoder<T>::NextNumRepeats() {
793
265
    if (repeat_count_ > 0) return repeat_count_;
794
10
    if (literal_count_ == 0) NextCounts();
795
10
    return repeat_count_;
796
265
}
_ZN5doris15RleBatchDecoderItE14NextNumRepeatsEv
Line
Count
Source
792
476k
int32_t RleBatchDecoder<T>::NextNumRepeats() {
793
476k
    if (repeat_count_ > 0) return repeat_count_;
794
476k
    if (literal_count_ == 0) NextCounts();
795
476k
    return repeat_count_;
796
476k
}
797
798
template <typename T>
799
185k
void RleBatchDecoder<T>::NextCounts() {
800
    // Read the next run's indicator int, it could be a literal or repeated run.
801
    // The int is encoded as a ULEB128-encoded value.
802
185k
    uint32_t indicator_value = 0;
803
185k
    if (UNLIKELY(!bit_reader_.GetUleb128<uint32_t>(&indicator_value))) {
804
2
        return;
805
2
    }
806
807
    // lsb indicates if it is a literal run or repeated run
808
185k
    bool is_literal = indicator_value & 1;
809
810
    // Don't try to handle run lengths that don't fit in an int32_t - just fail gracefully.
811
    // The Parquet standard does not allow longer runs - see PARQUET-1290.
812
185k
    uint32_t run_len = indicator_value >> 1;
813
185k
    if (is_literal) {
814
        // Use int64_t to avoid overflowing multiplication.
815
185k
        int64_t literal_count = static_cast<int64_t>(run_len) * 8;
816
185k
        if (UNLIKELY(literal_count > std::numeric_limits<int32_t>::max())) return;
817
185k
        literal_count_ = cast_set<int32_t>(literal_count);
818
185k
    } else {
819
690
        if (UNLIKELY(run_len == 0)) return;
820
690
        bool result = bit_reader_.GetBytes<T>(BitUtil::Ceil(bit_width_, 8), &repeated_value_);
821
690
        if (UNLIKELY(!result)) return;
822
690
        repeat_count_ = run_len;
823
690
    }
824
185k
}
_ZN5doris15RleBatchDecoderIjE10NextCountsEv
Line
Count
Source
799
46.7k
void RleBatchDecoder<T>::NextCounts() {
800
    // Read the next run's indicator int, it could be a literal or repeated run.
801
    // The int is encoded as a ULEB128-encoded value.
802
46.7k
    uint32_t indicator_value = 0;
803
46.7k
    if (UNLIKELY(!bit_reader_.GetUleb128<uint32_t>(&indicator_value))) {
804
0
        return;
805
0
    }
806
807
    // lsb indicates if it is a literal run or repeated run
808
46.7k
    bool is_literal = indicator_value & 1;
809
810
    // Don't try to handle run lengths that don't fit in an int32_t - just fail gracefully.
811
    // The Parquet standard does not allow longer runs - see PARQUET-1290.
812
46.7k
    uint32_t run_len = indicator_value >> 1;
813
46.7k
    if (is_literal) {
814
        // Use int64_t to avoid overflowing multiplication.
815
46.4k
        int64_t literal_count = static_cast<int64_t>(run_len) * 8;
816
46.4k
        if (UNLIKELY(literal_count > std::numeric_limits<int32_t>::max())) return;
817
46.4k
        literal_count_ = cast_set<int32_t>(literal_count);
818
46.4k
    } else {
819
330
        if (UNLIKELY(run_len == 0)) return;
820
330
        bool result = bit_reader_.GetBytes<T>(BitUtil::Ceil(bit_width_, 8), &repeated_value_);
821
330
        if (UNLIKELY(!result)) return;
822
330
        repeat_count_ = run_len;
823
330
    }
824
46.7k
}
_ZN5doris15RleBatchDecoderIhE10NextCountsEv
Line
Count
Source
799
8
void RleBatchDecoder<T>::NextCounts() {
800
    // Read the next run's indicator int, it could be a literal or repeated run.
801
    // The int is encoded as a ULEB128-encoded value.
802
8
    uint32_t indicator_value = 0;
803
8
    if (UNLIKELY(!bit_reader_.GetUleb128<uint32_t>(&indicator_value))) {
804
0
        return;
805
0
    }
806
807
    // lsb indicates if it is a literal run or repeated run
808
8
    bool is_literal = indicator_value & 1;
809
810
    // Don't try to handle run lengths that don't fit in an int32_t - just fail gracefully.
811
    // The Parquet standard does not allow longer runs - see PARQUET-1290.
812
8
    uint32_t run_len = indicator_value >> 1;
813
8
    if (is_literal) {
814
        // Use int64_t to avoid overflowing multiplication.
815
7
        int64_t literal_count = static_cast<int64_t>(run_len) * 8;
816
7
        if (UNLIKELY(literal_count > std::numeric_limits<int32_t>::max())) return;
817
7
        literal_count_ = cast_set<int32_t>(literal_count);
818
7
    } else {
819
1
        if (UNLIKELY(run_len == 0)) return;
820
1
        bool result = bit_reader_.GetBytes<T>(BitUtil::Ceil(bit_width_, 8), &repeated_value_);
821
1
        if (UNLIKELY(!result)) return;
822
1
        repeat_count_ = run_len;
823
1
    }
824
8
}
_ZN5doris15RleBatchDecoderItE10NextCountsEv
Line
Count
Source
799
139k
void RleBatchDecoder<T>::NextCounts() {
800
    // Read the next run's indicator int, it could be a literal or repeated run.
801
    // The int is encoded as a ULEB128-encoded value.
802
139k
    uint32_t indicator_value = 0;
803
139k
    if (UNLIKELY(!bit_reader_.GetUleb128<uint32_t>(&indicator_value))) {
804
2
        return;
805
2
    }
806
807
    // lsb indicates if it is a literal run or repeated run
808
139k
    bool is_literal = indicator_value & 1;
809
810
    // Don't try to handle run lengths that don't fit in an int32_t - just fail gracefully.
811
    // The Parquet standard does not allow longer runs - see PARQUET-1290.
812
139k
    uint32_t run_len = indicator_value >> 1;
813
139k
    if (is_literal) {
814
        // Use int64_t to avoid overflowing multiplication.
815
138k
        int64_t literal_count = static_cast<int64_t>(run_len) * 8;
816
138k
        if (UNLIKELY(literal_count > std::numeric_limits<int32_t>::max())) return;
817
138k
        literal_count_ = cast_set<int32_t>(literal_count);
818
138k
    } else {
819
359
        if (UNLIKELY(run_len == 0)) return;
820
359
        bool result = bit_reader_.GetBytes<T>(BitUtil::Ceil(bit_width_, 8), &repeated_value_);
821
359
        if (UNLIKELY(!result)) return;
822
359
        repeat_count_ = run_len;
823
359
    }
824
139k
}
825
826
template <typename T>
827
1.85k
T RleBatchDecoder<T>::GetRepeatedValue(int32_t num_repeats_to_consume) {
828
1.85k
    repeat_count_ -= num_repeats_to_consume;
829
1.85k
    return repeated_value_;
830
1.85k
}
_ZN5doris15RleBatchDecoderIjE16GetRepeatedValueEi
Line
Count
Source
827
693
T RleBatchDecoder<T>::GetRepeatedValue(int32_t num_repeats_to_consume) {
828
693
    repeat_count_ -= num_repeats_to_consume;
829
693
    return repeated_value_;
830
693
}
_ZN5doris15RleBatchDecoderIhE16GetRepeatedValueEi
Line
Count
Source
827
256
T RleBatchDecoder<T>::GetRepeatedValue(int32_t num_repeats_to_consume) {
828
256
    repeat_count_ -= num_repeats_to_consume;
829
256
    return repeated_value_;
830
256
}
_ZN5doris15RleBatchDecoderItE16GetRepeatedValueEi
Line
Count
Source
827
903
T RleBatchDecoder<T>::GetRepeatedValue(int32_t num_repeats_to_consume) {
828
903
    repeat_count_ -= num_repeats_to_consume;
829
903
    return repeated_value_;
830
903
}
831
832
template <typename T>
833
558k
int32_t RleBatchDecoder<T>::NextNumLiterals() {
834
558k
    if (literal_count_ > 0) return literal_count_;
835
1
    if (repeat_count_ == 0) NextCounts();
836
1
    return literal_count_;
837
558k
}
_ZN5doris15RleBatchDecoderIjE15NextNumLiteralsEv
Line
Count
Source
833
82.0k
int32_t RleBatchDecoder<T>::NextNumLiterals() {
834
82.0k
    if (literal_count_ > 0) return literal_count_;
835
0
    if (repeat_count_ == 0) NextCounts();
836
0
    return literal_count_;
837
82.0k
}
_ZN5doris15RleBatchDecoderIhE15NextNumLiteralsEv
Line
Count
Source
833
9
int32_t RleBatchDecoder<T>::NextNumLiterals() {
834
9
    if (literal_count_ > 0) return literal_count_;
835
0
    if (repeat_count_ == 0) NextCounts();
836
0
    return literal_count_;
837
9
}
_ZN5doris15RleBatchDecoderItE15NextNumLiteralsEv
Line
Count
Source
833
476k
int32_t RleBatchDecoder<T>::NextNumLiterals() {
834
476k
    if (literal_count_ > 0) return literal_count_;
835
1
    if (repeat_count_ == 0) NextCounts();
836
1
    return literal_count_;
837
476k
}
838
839
template <typename T>
840
558k
bool RleBatchDecoder<T>::GetLiteralValues(int32_t num_literals_to_consume, T* values) {
841
558k
    int32_t num_consumed = 0;
842
    // Copy any buffered literals left over from previous calls.
843
558k
    if (HaveBufferedLiterals()) {
844
372k
        num_consumed = OutputBufferedLiterals(num_literals_to_consume, values);
845
372k
    }
846
847
558k
    int32_t num_remaining = num_literals_to_consume - num_consumed;
848
    // Copy literals directly to the output, bypassing 'literal_buffer_' when possible.
849
    // Need to round to a batch of 32 if the caller is consuming only part of the current
850
    // run avoid ending on a non-byte boundary.
851
558k
    int32_t num_to_bypass =
852
558k
            std::min<int32_t>(literal_count_, BitUtil::RoundDownToPowerOf2(num_remaining, 32));
853
558k
    if (num_to_bypass > 0) {
854
55
        int num_read = bit_reader_.UnpackBatch(bit_width_, num_to_bypass, values + num_consumed);
855
        // If we couldn't read the expected number, that means the input was truncated.
856
55
        if (num_read < num_to_bypass) return false;
857
55
        literal_count_ -= num_to_bypass;
858
55
        num_consumed += num_to_bypass;
859
55
        num_remaining = num_literals_to_consume - num_consumed;
860
55
    }
861
862
558k
    if (num_remaining > 0) {
863
        // We weren't able to copy all the literals requested directly from the input.
864
        // Buffer literals and copy over the requested number.
865
185k
        if (UNLIKELY(!FillLiteralBuffer())) return false;
866
185k
        OutputBufferedLiterals(num_remaining, values + num_consumed);
867
185k
    }
868
558k
    return true;
869
558k
}
_ZN5doris15RleBatchDecoderIjE16GetLiteralValuesEiPj
Line
Count
Source
840
82.0k
bool RleBatchDecoder<T>::GetLiteralValues(int32_t num_literals_to_consume, T* values) {
841
82.0k
    int32_t num_consumed = 0;
842
    // Copy any buffered literals left over from previous calls.
843
82.0k
    if (HaveBufferedLiterals()) {
844
35.6k
        num_consumed = OutputBufferedLiterals(num_literals_to_consume, values);
845
35.6k
    }
846
847
82.0k
    int32_t num_remaining = num_literals_to_consume - num_consumed;
848
    // Copy literals directly to the output, bypassing 'literal_buffer_' when possible.
849
    // Need to round to a batch of 32 if the caller is consuming only part of the current
850
    // run avoid ending on a non-byte boundary.
851
82.0k
    int32_t num_to_bypass =
852
82.0k
            std::min<int32_t>(literal_count_, BitUtil::RoundDownToPowerOf2(num_remaining, 32));
853
82.0k
    if (num_to_bypass > 0) {
854
54
        int num_read = bit_reader_.UnpackBatch(bit_width_, num_to_bypass, values + num_consumed);
855
        // If we couldn't read the expected number, that means the input was truncated.
856
54
        if (num_read < num_to_bypass) return false;
857
54
        literal_count_ -= num_to_bypass;
858
54
        num_consumed += num_to_bypass;
859
54
        num_remaining = num_literals_to_consume - num_consumed;
860
54
    }
861
862
82.0k
    if (num_remaining > 0) {
863
        // We weren't able to copy all the literals requested directly from the input.
864
        // Buffer literals and copy over the requested number.
865
46.7k
        if (UNLIKELY(!FillLiteralBuffer())) return false;
866
46.7k
        OutputBufferedLiterals(num_remaining, values + num_consumed);
867
46.7k
    }
868
82.0k
    return true;
869
82.0k
}
_ZN5doris15RleBatchDecoderIhE16GetLiteralValuesEiPh
Line
Count
Source
840
9
bool RleBatchDecoder<T>::GetLiteralValues(int32_t num_literals_to_consume, T* values) {
841
9
    int32_t num_consumed = 0;
842
    // Copy any buffered literals left over from previous calls.
843
9
    if (HaveBufferedLiterals()) {
844
2
        num_consumed = OutputBufferedLiterals(num_literals_to_consume, values);
845
2
    }
846
847
9
    int32_t num_remaining = num_literals_to_consume - num_consumed;
848
    // Copy literals directly to the output, bypassing 'literal_buffer_' when possible.
849
    // Need to round to a batch of 32 if the caller is consuming only part of the current
850
    // run avoid ending on a non-byte boundary.
851
9
    int32_t num_to_bypass =
852
9
            std::min<int32_t>(literal_count_, BitUtil::RoundDownToPowerOf2(num_remaining, 32));
853
9
    if (num_to_bypass > 0) {
854
0
        int num_read = bit_reader_.UnpackBatch(bit_width_, num_to_bypass, values + num_consumed);
855
        // If we couldn't read the expected number, that means the input was truncated.
856
0
        if (num_read < num_to_bypass) return false;
857
0
        literal_count_ -= num_to_bypass;
858
0
        num_consumed += num_to_bypass;
859
0
        num_remaining = num_literals_to_consume - num_consumed;
860
0
    }
861
862
9
    if (num_remaining > 0) {
863
        // We weren't able to copy all the literals requested directly from the input.
864
        // Buffer literals and copy over the requested number.
865
7
        if (UNLIKELY(!FillLiteralBuffer())) return false;
866
4
        OutputBufferedLiterals(num_remaining, values + num_consumed);
867
4
    }
868
6
    return true;
869
9
}
_ZN5doris15RleBatchDecoderItE16GetLiteralValuesEiPt
Line
Count
Source
840
476k
bool RleBatchDecoder<T>::GetLiteralValues(int32_t num_literals_to_consume, T* values) {
841
476k
    int32_t num_consumed = 0;
842
    // Copy any buffered literals left over from previous calls.
843
476k
    if (HaveBufferedLiterals()) {
844
337k
        num_consumed = OutputBufferedLiterals(num_literals_to_consume, values);
845
337k
    }
846
847
476k
    int32_t num_remaining = num_literals_to_consume - num_consumed;
848
    // Copy literals directly to the output, bypassing 'literal_buffer_' when possible.
849
    // Need to round to a batch of 32 if the caller is consuming only part of the current
850
    // run avoid ending on a non-byte boundary.
851
476k
    int32_t num_to_bypass =
852
476k
            std::min<int32_t>(literal_count_, BitUtil::RoundDownToPowerOf2(num_remaining, 32));
853
476k
    if (num_to_bypass > 0) {
854
1
        int num_read = bit_reader_.UnpackBatch(bit_width_, num_to_bypass, values + num_consumed);
855
        // If we couldn't read the expected number, that means the input was truncated.
856
1
        if (num_read < num_to_bypass) return false;
857
1
        literal_count_ -= num_to_bypass;
858
1
        num_consumed += num_to_bypass;
859
1
        num_remaining = num_literals_to_consume - num_consumed;
860
1
    }
861
862
476k
    if (num_remaining > 0) {
863
        // We weren't able to copy all the literals requested directly from the input.
864
        // Buffer literals and copy over the requested number.
865
138k
        if (UNLIKELY(!FillLiteralBuffer())) return false;
866
138k
        OutputBufferedLiterals(num_remaining, values + num_consumed);
867
138k
    }
868
476k
    return true;
869
476k
}
870
871
template <typename T>
872
185k
bool RleBatchDecoder<T>::FillLiteralBuffer() {
873
185k
    int32_t num_to_buffer = std::min<int32_t>(LITERAL_BUFFER_LEN, literal_count_);
874
185k
    num_buffered_literals_ = bit_reader_.UnpackBatch(bit_width_, num_to_buffer, literal_buffer_);
875
    // If we couldn't read the expected number, that means the input was truncated.
876
185k
    if (UNLIKELY(num_buffered_literals_ < num_to_buffer)) return false;
877
185k
    literal_buffer_pos_ = 0;
878
185k
    return true;
879
185k
}
_ZN5doris15RleBatchDecoderIjE17FillLiteralBufferEv
Line
Count
Source
872
46.7k
bool RleBatchDecoder<T>::FillLiteralBuffer() {
873
46.7k
    int32_t num_to_buffer = std::min<int32_t>(LITERAL_BUFFER_LEN, literal_count_);
874
46.7k
    num_buffered_literals_ = bit_reader_.UnpackBatch(bit_width_, num_to_buffer, literal_buffer_);
875
    // If we couldn't read the expected number, that means the input was truncated.
876
46.7k
    if (UNLIKELY(num_buffered_literals_ < num_to_buffer)) return false;
877
46.7k
    literal_buffer_pos_ = 0;
878
46.7k
    return true;
879
46.7k
}
_ZN5doris15RleBatchDecoderIhE17FillLiteralBufferEv
Line
Count
Source
872
7
bool RleBatchDecoder<T>::FillLiteralBuffer() {
873
7
    int32_t num_to_buffer = std::min<int32_t>(LITERAL_BUFFER_LEN, literal_count_);
874
7
    num_buffered_literals_ = bit_reader_.UnpackBatch(bit_width_, num_to_buffer, literal_buffer_);
875
    // If we couldn't read the expected number, that means the input was truncated.
876
7
    if (UNLIKELY(num_buffered_literals_ < num_to_buffer)) return false;
877
4
    literal_buffer_pos_ = 0;
878
4
    return true;
879
7
}
_ZN5doris15RleBatchDecoderItE17FillLiteralBufferEv
Line
Count
Source
872
138k
bool RleBatchDecoder<T>::FillLiteralBuffer() {
873
138k
    int32_t num_to_buffer = std::min<int32_t>(LITERAL_BUFFER_LEN, literal_count_);
874
138k
    num_buffered_literals_ = bit_reader_.UnpackBatch(bit_width_, num_to_buffer, literal_buffer_);
875
    // If we couldn't read the expected number, that means the input was truncated.
876
138k
    if (UNLIKELY(num_buffered_literals_ < num_to_buffer)) return false;
877
138k
    literal_buffer_pos_ = 0;
878
138k
    return true;
879
138k
}
880
881
template <typename T>
882
527k
uint32_t RleBatchDecoder<T>::GetBatch(T* values, uint32_t batch_num) {
883
527k
    uint32_t num_consumed = 0;
884
1.05M
    while (num_consumed < batch_num) {
885
        // Add RLE encoded values by repeating the current value this number of times.
886
527k
        uint32_t num_repeats = NextNumRepeats();
887
527k
        if (num_repeats > 0) {
888
1.47k
            int32_t num_repeats_to_set = std::min(num_repeats, batch_num - num_consumed);
889
1.47k
            T repeated_value = GetRepeatedValue(num_repeats_to_set);
890
2.16M
            for (int i = 0; i < num_repeats_to_set; ++i) {
891
2.16M
                values[num_consumed + i] = repeated_value;
892
2.16M
            }
893
1.47k
            num_consumed += num_repeats_to_set;
894
1.47k
            continue;
895
1.47k
        }
896
897
        // Add remaining literal values, if any.
898
525k
        uint32_t num_literals = NextNumLiterals();
899
525k
        if (num_literals == 0) {
900
1
            break;
901
1
        }
902
525k
        uint32_t num_literals_to_set = std::min(num_literals, batch_num - num_consumed);
903
525k
        if (!GetLiteralValues(num_literals_to_set, values + num_consumed)) {
904
4
            return 0;
905
4
        }
906
525k
        num_consumed += num_literals_to_set;
907
525k
    }
908
527k
    return num_consumed;
909
527k
}
_ZN5doris15RleBatchDecoderIjE8GetBatchEPjj
Line
Count
Source
882
50.4k
uint32_t RleBatchDecoder<T>::GetBatch(T* values, uint32_t batch_num) {
883
50.4k
    uint32_t num_consumed = 0;
884
100k
    while (num_consumed < batch_num) {
885
        // Add RLE encoded values by repeating the current value this number of times.
886
50.3k
        uint32_t num_repeats = NextNumRepeats();
887
50.3k
        if (num_repeats > 0) {
888
387
            int32_t num_repeats_to_set = std::min(num_repeats, batch_num - num_consumed);
889
387
            T repeated_value = GetRepeatedValue(num_repeats_to_set);
890
1.09M
            for (int i = 0; i < num_repeats_to_set; ++i) {
891
1.09M
                values[num_consumed + i] = repeated_value;
892
1.09M
            }
893
387
            num_consumed += num_repeats_to_set;
894
387
            continue;
895
387
        }
896
897
        // Add remaining literal values, if any.
898
49.9k
        uint32_t num_literals = NextNumLiterals();
899
49.9k
        if (num_literals == 0) {
900
0
            break;
901
0
        }
902
49.9k
        uint32_t num_literals_to_set = std::min(num_literals, batch_num - num_consumed);
903
49.9k
        if (!GetLiteralValues(num_literals_to_set, values + num_consumed)) {
904
0
            return 0;
905
0
        }
906
49.9k
        num_consumed += num_literals_to_set;
907
49.9k
    }
908
50.4k
    return num_consumed;
909
50.4k
}
_ZN5doris15RleBatchDecoderIhE8GetBatchEPhj
Line
Count
Source
882
263
uint32_t RleBatchDecoder<T>::GetBatch(T* values, uint32_t batch_num) {
883
263
    uint32_t num_consumed = 0;
884
525
    while (num_consumed < batch_num) {
885
        // Add RLE encoded values by repeating the current value this number of times.
886
265
        uint32_t num_repeats = NextNumRepeats();
887
265
        if (num_repeats > 0) {
888
256
            int32_t num_repeats_to_set = std::min(num_repeats, batch_num - num_consumed);
889
256
            T repeated_value = GetRepeatedValue(num_repeats_to_set);
890
1.04M
            for (int i = 0; i < num_repeats_to_set; ++i) {
891
1.04M
                values[num_consumed + i] = repeated_value;
892
1.04M
            }
893
256
            num_consumed += num_repeats_to_set;
894
256
            continue;
895
256
        }
896
897
        // Add remaining literal values, if any.
898
9
        uint32_t num_literals = NextNumLiterals();
899
9
        if (num_literals == 0) {
900
0
            break;
901
0
        }
902
9
        uint32_t num_literals_to_set = std::min(num_literals, batch_num - num_consumed);
903
9
        if (!GetLiteralValues(num_literals_to_set, values + num_consumed)) {
904
3
            return 0;
905
3
        }
906
6
        num_consumed += num_literals_to_set;
907
6
    }
908
260
    return num_consumed;
909
263
}
_ZN5doris15RleBatchDecoderItE8GetBatchEPtj
Line
Count
Source
882
476k
uint32_t RleBatchDecoder<T>::GetBatch(T* values, uint32_t batch_num) {
883
476k
    uint32_t num_consumed = 0;
884
953k
    while (num_consumed < batch_num) {
885
        // Add RLE encoded values by repeating the current value this number of times.
886
476k
        uint32_t num_repeats = NextNumRepeats();
887
476k
        if (num_repeats > 0) {
888
835
            int32_t num_repeats_to_set = std::min(num_repeats, batch_num - num_consumed);
889
835
            T repeated_value = GetRepeatedValue(num_repeats_to_set);
890
20.9k
            for (int i = 0; i < num_repeats_to_set; ++i) {
891
20.1k
                values[num_consumed + i] = repeated_value;
892
20.1k
            }
893
835
            num_consumed += num_repeats_to_set;
894
835
            continue;
895
835
        }
896
897
        // Add remaining literal values, if any.
898
475k
        uint32_t num_literals = NextNumLiterals();
899
475k
        if (num_literals == 0) {
900
1
            break;
901
1
        }
902
475k
        uint32_t num_literals_to_set = std::min(num_literals, batch_num - num_consumed);
903
475k
        if (!GetLiteralValues(num_literals_to_set, values + num_consumed)) {
904
1
            return 0;
905
1
        }
906
475k
        num_consumed += num_literals_to_set;
907
475k
    }
908
476k
    return num_consumed;
909
476k
}
910
#include "common/compile_check_end.h"
911
} // namespace doris