Coverage Report

Created: 2026-03-22 10:02

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
be/src/util/bit_stream_utils.inline.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
// This file is copied from
18
// https://github.com/apache/impala/blob/branch-2.9.0/be/src/util/bit-stream-utils.inline.h
19
// and modified by Doris
20
21
#pragma once
22
23
#include <algorithm>
24
25
#include "glog/logging.h"
26
#include "util/alignment.h"
27
#include "util/bit_packing.inline.h"
28
#include "util/bit_stream_utils.h"
29
#include "util/bit_util.h"
30
31
using doris::BitUtil;
32
33
namespace doris {
34
#include "common/compile_check_begin.h"
35
21.4M
inline void BitWriter::PutValue(uint64_t v, int num_bits) {
36
21.4M
    DCHECK_LE(num_bits, 64);
37
    // Truncate the higher-order bits. This is necessary to
38
    // support signed values.
39
21.4M
    v &= ~0ULL >> (64 - num_bits);
40
41
21.4M
    buffered_values_ |= v << bit_offset_;
42
21.4M
    bit_offset_ += num_bits;
43
44
21.4M
    if (bit_offset_ >= 64) [[unlikely]] {
45
        // Flush buffered_values_ and write out bits of v that did not fit
46
280k
        buffer_->reserve(ALIGN_UP(byte_offset_ + 8, 8));
47
280k
        buffer_->resize(byte_offset_ + 8);
48
280k
        DCHECK_LE(byte_offset_ + 8, buffer_->capacity());
49
280k
        memcpy(buffer_->data() + byte_offset_, &buffered_values_, 8);
50
280k
        buffered_values_ = 0;
51
280k
        byte_offset_ += 8;
52
280k
        bit_offset_ -= 64;
53
280k
        buffered_values_ = BitUtil::ShiftRightZeroOnOverflow(v, (num_bits - bit_offset_));
54
280k
    }
55
21.4M
    DCHECK_LT(bit_offset_, 64);
56
21.4M
}
57
58
71.3M
inline void BitWriter::Flush(bool align) {
59
71.3M
    int num_bytes = BitUtil::Ceil(bit_offset_, 8);
60
71.3M
    buffer_->reserve(ALIGN_UP(byte_offset_ + num_bytes, 8));
61
71.3M
    buffer_->resize(byte_offset_ + num_bytes);
62
71.3M
    DCHECK_LE(byte_offset_ + num_bytes, buffer_->capacity());
63
71.3M
    memcpy(buffer_->data() + byte_offset_, &buffered_values_, num_bytes);
64
65
71.3M
    if (align) {
66
60.1M
        buffered_values_ = 0;
67
60.1M
        byte_offset_ += num_bytes;
68
60.1M
        bit_offset_ = 0;
69
60.1M
    }
70
71.3M
}
71
72
60.1M
inline uint8_t* BitWriter::GetNextBytePtr(int num_bytes) {
73
60.1M
    Flush(/* align */ true);
74
60.1M
    buffer_->reserve(ALIGN_UP(byte_offset_ + num_bytes, 8));
75
60.1M
    buffer_->resize(byte_offset_ + num_bytes);
76
60.1M
    uint8_t* ptr = buffer_->data() + byte_offset_;
77
60.1M
    byte_offset_ += num_bytes;
78
60.1M
    DCHECK_LE(byte_offset_, buffer_->capacity());
79
60.1M
    return ptr;
80
60.1M
}
81
82
template <typename T>
83
58.9M
void BitWriter::PutAligned(T val, int num_bytes) {
84
58.9M
    DCHECK_LE(num_bytes, sizeof(T));
85
58.9M
    uint8_t* ptr = GetNextBytePtr(num_bytes);
86
58.9M
    memcpy(ptr, &val, num_bytes);
87
58.9M
}
_ZN5doris9BitWriter10PutAlignedIhEEvT_i
Line
Count
Source
83
38.5M
void BitWriter::PutAligned(T val, int num_bytes) {
84
    DCHECK_LE(num_bytes, sizeof(T));
85
38.5M
    uint8_t* ptr = GetNextBytePtr(num_bytes);
86
38.5M
    memcpy(ptr, &val, num_bytes);
87
38.5M
}
_ZN5doris9BitWriter10PutAlignedImEEvT_i
Line
Count
Source
83
20.3M
void BitWriter::PutAligned(T val, int num_bytes) {
84
    DCHECK_LE(num_bytes, sizeof(T));
85
20.3M
    uint8_t* ptr = GetNextBytePtr(num_bytes);
86
20.3M
    memcpy(ptr, &val, num_bytes);
87
20.3M
}
88
89
20.3M
inline void BitWriter::PutVlqInt(int32_t v) {
90
38.5M
    while ((v & 0xFFFFFF80) != 0L) {
91
18.1M
        PutAligned<uint8_t>((v & 0x7F) | 0x80, 1);
92
18.1M
        v >>= 7;
93
18.1M
    }
94
20.3M
    PutAligned<uint8_t>(v & 0x7F, 1);
95
20.3M
}
96
97
inline BitReader::BitReader(const uint8_t* buffer, int buffer_len)
98
1.49M
        : buffer_(buffer),
99
1.49M
          max_bytes_(buffer_len),
100
1.49M
          buffered_values_(0),
101
1.49M
          byte_offset_(0),
102
1.49M
          bit_offset_(0) {
103
1.49M
    int num_bytes = std::min(8, max_bytes_);
104
1.49M
    memcpy(&buffered_values_, buffer_ + byte_offset_, num_bytes);
105
1.49M
}
106
107
2.78M
inline void BitReader::BufferValues() {
108
2.78M
    int bytes_remaining = max_bytes_ - byte_offset_;
109
2.78M
    if (bytes_remaining >= 8) [[likely]] {
110
2.73M
        memcpy(&buffered_values_, buffer_ + byte_offset_, 8);
111
2.73M
    } else {
112
44.0k
        memcpy(&buffered_values_, buffer_ + byte_offset_, bytes_remaining);
113
44.0k
    }
114
2.78M
}
115
116
template <typename T>
117
130M
bool BitReader::GetValue(int num_bits, T* v) {
118
130M
    DCHECK_LE(num_bits, 64);
119
130M
    DCHECK_LE(num_bits, sizeof(T) * 8);
120
121
130M
    if (byte_offset_ * 8 + bit_offset_ + num_bits > max_bytes_ * 8) [[unlikely]] {
122
0
        return false;
123
0
    }
124
125
130M
    *v = static_cast<T>(BitUtil::TrailingBits(buffered_values_, bit_offset_ + num_bits) >>
126
130M
                        bit_offset_);
127
128
130M
    bit_offset_ += num_bits;
129
130M
    if (bit_offset_ >= 64) {
130
2.77M
        byte_offset_ += 8;
131
2.77M
        bit_offset_ -= 64;
132
2.77M
        BufferValues();
133
        // Read bits of v that crossed into new buffered_values_
134
2.77M
        *v |= BitUtil::ShiftLeftZeroOnOverflow(BitUtil::TrailingBits(buffered_values_, bit_offset_),
135
2.77M
                                               (num_bits - bit_offset_));
136
2.77M
    }
137
130M
    DCHECK_LE(bit_offset_, 64);
138
130M
    return true;
139
130M
}
_ZN5doris9BitReader8GetValueIsEEbiPT_
Line
Count
Source
117
84.1M
bool BitReader::GetValue(int num_bits, T* v) {
118
84.1M
    DCHECK_LE(num_bits, 64);
119
84.1M
    DCHECK_LE(num_bits, sizeof(T) * 8);
120
121
84.1M
    if (byte_offset_ * 8 + bit_offset_ + num_bits > max_bytes_ * 8) [[unlikely]] {
122
0
        return false;
123
0
    }
124
125
84.1M
    *v = static_cast<T>(BitUtil::TrailingBits(buffered_values_, bit_offset_ + num_bits) >>
126
84.1M
                        bit_offset_);
127
128
84.1M
    bit_offset_ += num_bits;
129
84.1M
    if (bit_offset_ >= 64) {
130
1.95M
        byte_offset_ += 8;
131
1.95M
        bit_offset_ -= 64;
132
1.95M
        BufferValues();
133
        // Read bits of v that crossed into new buffered_values_
134
1.95M
        *v |= BitUtil::ShiftLeftZeroOnOverflow(BitUtil::TrailingBits(buffered_values_, bit_offset_),
135
1.95M
                                               (num_bits - bit_offset_));
136
1.95M
    }
137
    DCHECK_LE(bit_offset_, 64);
138
84.1M
    return true;
139
84.1M
}
_ZN5doris9BitReader8GetValueImEEbiPT_
Line
Count
Source
117
13.1M
bool BitReader::GetValue(int num_bits, T* v) {
118
13.1M
    DCHECK_LE(num_bits, 64);
119
13.1M
    DCHECK_LE(num_bits, sizeof(T) * 8);
120
121
13.1M
    if (byte_offset_ * 8 + bit_offset_ + num_bits > max_bytes_ * 8) [[unlikely]] {
122
0
        return false;
123
0
    }
124
125
13.1M
    *v = static_cast<T>(BitUtil::TrailingBits(buffered_values_, bit_offset_ + num_bits) >>
126
13.1M
                        bit_offset_);
127
128
13.1M
    bit_offset_ += num_bits;
129
13.1M
    if (bit_offset_ >= 64) {
130
72.0k
        byte_offset_ += 8;
131
72.0k
        bit_offset_ -= 64;
132
72.0k
        BufferValues();
133
        // Read bits of v that crossed into new buffered_values_
134
72.0k
        *v |= BitUtil::ShiftLeftZeroOnOverflow(BitUtil::TrailingBits(buffered_values_, bit_offset_),
135
72.0k
                                               (num_bits - bit_offset_));
136
72.0k
    }
137
    DCHECK_LE(bit_offset_, 64);
138
13.1M
    return true;
139
13.1M
}
_ZN5doris9BitReader8GetValueIbEEbiPT_
Line
Count
Source
117
10.8M
bool BitReader::GetValue(int num_bits, T* v) {
118
10.8M
    DCHECK_LE(num_bits, 64);
119
10.8M
    DCHECK_LE(num_bits, sizeof(T) * 8);
120
121
10.8M
    if (byte_offset_ * 8 + bit_offset_ + num_bits > max_bytes_ * 8) [[unlikely]] {
122
0
        return false;
123
0
    }
124
125
10.8M
    *v = static_cast<T>(BitUtil::TrailingBits(buffered_values_, bit_offset_ + num_bits) >>
126
10.8M
                        bit_offset_);
127
128
10.8M
    bit_offset_ += num_bits;
129
10.8M
    if (bit_offset_ >= 64) {
130
50.7k
        byte_offset_ += 8;
131
50.7k
        bit_offset_ -= 64;
132
50.7k
        BufferValues();
133
        // Read bits of v that crossed into new buffered_values_
134
50.7k
        *v |= BitUtil::ShiftLeftZeroOnOverflow(BitUtil::TrailingBits(buffered_values_, bit_offset_),
135
50.7k
                                               (num_bits - bit_offset_));
136
50.7k
    }
137
    DCHECK_LE(bit_offset_, 64);
138
10.8M
    return true;
139
10.8M
}
_ZN5doris9BitReader8GetValueIhEEbiPT_
Line
Count
Source
117
20.9M
bool BitReader::GetValue(int num_bits, T* v) {
118
20.9M
    DCHECK_LE(num_bits, 64);
119
20.9M
    DCHECK_LE(num_bits, sizeof(T) * 8);
120
121
20.9M
    if (byte_offset_ * 8 + bit_offset_ + num_bits > max_bytes_ * 8) [[unlikely]] {
122
0
        return false;
123
0
    }
124
125
20.9M
    *v = static_cast<T>(BitUtil::TrailingBits(buffered_values_, bit_offset_ + num_bits) >>
126
20.9M
                        bit_offset_);
127
128
20.9M
    bit_offset_ += num_bits;
129
20.9M
    if (bit_offset_ >= 64) {
130
303k
        byte_offset_ += 8;
131
303k
        bit_offset_ -= 64;
132
303k
        BufferValues();
133
        // Read bits of v that crossed into new buffered_values_
134
303k
        *v |= BitUtil::ShiftLeftZeroOnOverflow(BitUtil::TrailingBits(buffered_values_, bit_offset_),
135
303k
                                               (num_bits - bit_offset_));
136
303k
    }
137
    DCHECK_LE(bit_offset_, 64);
138
20.9M
    return true;
139
20.9M
}
_ZN5doris9BitReader8GetValueIiEEbiPT_
Line
Count
Source
117
196k
bool BitReader::GetValue(int num_bits, T* v) {
118
196k
    DCHECK_LE(num_bits, 64);
119
196k
    DCHECK_LE(num_bits, sizeof(T) * 8);
120
121
196k
    if (byte_offset_ * 8 + bit_offset_ + num_bits > max_bytes_ * 8) [[unlikely]] {
122
0
        return false;
123
0
    }
124
125
196k
    *v = static_cast<T>(BitUtil::TrailingBits(buffered_values_, bit_offset_ + num_bits) >>
126
196k
                        bit_offset_);
127
128
196k
    bit_offset_ += num_bits;
129
196k
    if (bit_offset_ >= 64) {
130
11.3k
        byte_offset_ += 8;
131
11.3k
        bit_offset_ -= 64;
132
11.3k
        BufferValues();
133
        // Read bits of v that crossed into new buffered_values_
134
11.3k
        *v |= BitUtil::ShiftLeftZeroOnOverflow(BitUtil::TrailingBits(buffered_values_, bit_offset_),
135
11.3k
                                               (num_bits - bit_offset_));
136
11.3k
    }
137
    DCHECK_LE(bit_offset_, 64);
138
196k
    return true;
139
196k
}
_ZN5doris9BitReader8GetValueIlEEbiPT_
Line
Count
Source
117
541k
bool BitReader::GetValue(int num_bits, T* v) {
118
541k
    DCHECK_LE(num_bits, 64);
119
541k
    DCHECK_LE(num_bits, sizeof(T) * 8);
120
121
541k
    if (byte_offset_ * 8 + bit_offset_ + num_bits > max_bytes_ * 8) [[unlikely]] {
122
0
        return false;
123
0
    }
124
125
541k
    *v = static_cast<T>(BitUtil::TrailingBits(buffered_values_, bit_offset_ + num_bits) >>
126
541k
                        bit_offset_);
127
128
541k
    bit_offset_ += num_bits;
129
541k
    if (bit_offset_ >= 64) {
130
286k
        byte_offset_ += 8;
131
286k
        bit_offset_ -= 64;
132
286k
        BufferValues();
133
        // Read bits of v that crossed into new buffered_values_
134
286k
        *v |= BitUtil::ShiftLeftZeroOnOverflow(BitUtil::TrailingBits(buffered_values_, bit_offset_),
135
286k
                                               (num_bits - bit_offset_));
136
286k
    }
137
    DCHECK_LE(bit_offset_, 64);
138
541k
    return true;
139
541k
}
_ZN5doris9BitReader8GetValueIcEEbiPT_
Line
Count
Source
117
789k
bool BitReader::GetValue(int num_bits, T* v) {
118
789k
    DCHECK_LE(num_bits, 64);
119
789k
    DCHECK_LE(num_bits, sizeof(T) * 8);
120
121
789k
    if (byte_offset_ * 8 + bit_offset_ + num_bits > max_bytes_ * 8) [[unlikely]] {
122
0
        return false;
123
0
    }
124
125
789k
    *v = static_cast<T>(BitUtil::TrailingBits(buffered_values_, bit_offset_ + num_bits) >>
126
789k
                        bit_offset_);
127
128
789k
    bit_offset_ += num_bits;
129
789k
    if (bit_offset_ >= 64) {
130
98.6k
        byte_offset_ += 8;
131
98.6k
        bit_offset_ -= 64;
132
98.6k
        BufferValues();
133
        // Read bits of v that crossed into new buffered_values_
134
98.6k
        *v |= BitUtil::ShiftLeftZeroOnOverflow(BitUtil::TrailingBits(buffered_values_, bit_offset_),
135
98.6k
                                               (num_bits - bit_offset_));
136
98.6k
    }
137
    DCHECK_LE(bit_offset_, 64);
138
789k
    return true;
139
789k
}
140
141
4.49M
inline void BitReader::Rewind(int num_bits) {
142
4.49M
    bit_offset_ -= num_bits;
143
4.49M
    if (bit_offset_ >= 0) {
144
4.47M
        return;
145
4.47M
    }
146
29.9k
    while (bit_offset_ < 0) {
147
15.8k
        int seek_back = std::min(byte_offset_, 8);
148
15.8k
        byte_offset_ -= seek_back;
149
15.8k
        bit_offset_ += seek_back * 8;
150
15.8k
    }
151
    // This should only be executed *if* rewinding by 'num_bits'
152
    // make the existing buffered_values_ invalid
153
14.0k
    DCHECK_GE(byte_offset_, 0); // Check for underflow
154
14.0k
    memcpy(&buffered_values_, buffer_ + byte_offset_, 8);
155
14.0k
}
156
157
1.30k
inline bool BitReader::Advance(int64_t num_bits) {
158
1.30k
    int64_t bits_required = bit_offset_ + num_bits;
159
1.30k
    int64_t bytes_required = (bits_required >> 3) + ((bits_required & 7) != 0);
160
1.30k
    if (bytes_required > max_bytes_ - byte_offset_) {
161
0
        return false;
162
0
    }
163
1.30k
    byte_offset_ += static_cast<int>(bits_required >> 3);
164
1.30k
    bit_offset_ = static_cast<int>(bits_required & 7);
165
1.30k
    BufferValues();
166
1.30k
    return true;
167
1.30k
}
168
169
0
inline void BitReader::SeekToBit(unsigned int stream_position) {
170
0
    DCHECK_LE(stream_position, max_bytes_ * 8);
171
0
172
0
    int delta = static_cast<int>(stream_position) - position();
173
0
    if (delta == 0) {
174
0
        return;
175
0
    } else if (delta < 0) {
176
0
        Rewind(position() - stream_position);
177
0
    } else {
178
0
        bit_offset_ += delta;
179
0
        while (bit_offset_ >= 64) {
180
0
            byte_offset_ += 8;
181
0
            bit_offset_ -= 64;
182
0
            if (bit_offset_ < 64) {
183
0
                // This should only be executed if seeking to
184
0
                // 'stream_position' makes the existing buffered_values_
185
0
                // invalid.
186
0
                BufferValues();
187
0
            }
188
0
        }
189
0
    }
190
0
}
191
192
template <typename T>
193
16.6M
bool BitReader::GetAligned(int num_bytes, T* v) {
194
16.6M
    DCHECK_LE(num_bytes, sizeof(T));
195
16.6M
    int bytes_read = BitUtil::Ceil(bit_offset_, 8);
196
16.6M
    if (byte_offset_ + bytes_read + num_bytes > max_bytes_) [[unlikely]] {
197
12.4k
        return false;
198
12.4k
    }
199
200
    // Advance byte_offset to next unread byte and read num_bytes
201
16.6M
    byte_offset_ += bytes_read;
202
16.6M
    memcpy(v, buffer_ + byte_offset_, num_bytes);
203
16.6M
    byte_offset_ += num_bytes;
204
205
    // Reset buffered_values_
206
16.6M
    bit_offset_ = 0;
207
16.6M
    int bytes_remaining = max_bytes_ - byte_offset_;
208
16.6M
    if (bytes_remaining >= 8) [[likely]] {
209
13.7M
        memcpy(&buffered_values_, buffer_ + byte_offset_, 8);
210
13.7M
    } else {
211
2.90M
        memcpy(&buffered_values_, buffer_ + byte_offset_, bytes_remaining);
212
2.90M
    }
213
16.6M
    return true;
214
16.6M
}
_ZN5doris9BitReader10GetAlignedIhEEbiPT_
Line
Count
Source
193
11.5M
bool BitReader::GetAligned(int num_bytes, T* v) {
194
11.5M
    DCHECK_LE(num_bytes, sizeof(T));
195
11.5M
    int bytes_read = BitUtil::Ceil(bit_offset_, 8);
196
11.5M
    if (byte_offset_ + bytes_read + num_bytes > max_bytes_) [[unlikely]] {
197
12.4k
        return false;
198
12.4k
    }
199
200
    // Advance byte_offset to next unread byte and read num_bytes
201
11.5M
    byte_offset_ += bytes_read;
202
11.5M
    memcpy(v, buffer_ + byte_offset_, num_bytes);
203
11.5M
    byte_offset_ += num_bytes;
204
205
    // Reset buffered_values_
206
11.5M
    bit_offset_ = 0;
207
11.5M
    int bytes_remaining = max_bytes_ - byte_offset_;
208
11.5M
    if (bytes_remaining >= 8) [[likely]] {
209
9.66M
        memcpy(&buffered_values_, buffer_ + byte_offset_, 8);
210
9.66M
    } else {
211
1.88M
        memcpy(&buffered_values_, buffer_ + byte_offset_, bytes_remaining);
212
1.88M
    }
213
11.5M
    return true;
214
11.5M
}
_ZN5doris9BitReader10GetAlignedIsEEbiPT_
Line
Count
Source
193
4.04M
bool BitReader::GetAligned(int num_bytes, T* v) {
194
4.04M
    DCHECK_LE(num_bytes, sizeof(T));
195
4.04M
    int bytes_read = BitUtil::Ceil(bit_offset_, 8);
196
4.04M
    if (byte_offset_ + bytes_read + num_bytes > max_bytes_) [[unlikely]] {
197
0
        return false;
198
0
    }
199
200
    // Advance byte_offset to next unread byte and read num_bytes
201
4.04M
    byte_offset_ += bytes_read;
202
4.04M
    memcpy(v, buffer_ + byte_offset_, num_bytes);
203
4.04M
    byte_offset_ += num_bytes;
204
205
    // Reset buffered_values_
206
4.04M
    bit_offset_ = 0;
207
4.04M
    int bytes_remaining = max_bytes_ - byte_offset_;
208
4.04M
    if (bytes_remaining >= 8) [[likely]] {
209
3.34M
        memcpy(&buffered_values_, buffer_ + byte_offset_, 8);
210
3.34M
    } else {
211
701k
        memcpy(&buffered_values_, buffer_ + byte_offset_, bytes_remaining);
212
701k
    }
213
4.04M
    return true;
214
4.04M
}
_ZN5doris9BitReader10GetAlignedIbEEbiPT_
Line
Count
Source
193
1.02M
bool BitReader::GetAligned(int num_bytes, T* v) {
194
1.02M
    DCHECK_LE(num_bytes, sizeof(T));
195
1.02M
    int bytes_read = BitUtil::Ceil(bit_offset_, 8);
196
1.02M
    if (byte_offset_ + bytes_read + num_bytes > max_bytes_) [[unlikely]] {
197
0
        return false;
198
0
    }
199
200
    // Advance byte_offset to next unread byte and read num_bytes
201
1.02M
    byte_offset_ += bytes_read;
202
1.02M
    memcpy(v, buffer_ + byte_offset_, num_bytes);
203
1.02M
    byte_offset_ += num_bytes;
204
205
    // Reset buffered_values_
206
1.02M
    bit_offset_ = 0;
207
1.02M
    int bytes_remaining = max_bytes_ - byte_offset_;
208
1.02M
    if (bytes_remaining >= 8) [[likely]] {
209
704k
        memcpy(&buffered_values_, buffer_ + byte_offset_, 8);
210
704k
    } else {
211
319k
        memcpy(&buffered_values_, buffer_ + byte_offset_, bytes_remaining);
212
319k
    }
213
1.02M
    return true;
214
1.02M
}
215
216
9.92M
inline bool BitReader::GetVlqInt(uint32_t* v) {
217
9.92M
    uint32_t tmp = 0;
218
11.5M
    for (int num_bytes = 0; num_bytes < MAX_VLQ_BYTE_LEN; num_bytes++) {
219
11.5M
        uint8_t byte = 0;
220
11.5M
        if (!GetAligned<uint8_t>(1, &byte)) return false;
221
11.4M
        tmp |= static_cast<uint32_t>(byte & 0x7F) << (7 * num_bytes);
222
11.4M
        if ((byte & 0x80) == 0) {
223
9.91M
            *v = tmp;
224
9.91M
            return true;
225
9.91M
        }
226
11.4M
    }
227
18.4E
    return false;
228
9.92M
}
229
230
2.29k
inline bool BitReader::GetZigZagVlqInt(int32_t* v) {
231
2.29k
    uint32_t u;
232
2.29k
    if (!GetVlqInt(&u)) {
233
3
        return false;
234
3
    }
235
2.29k
    u = (u >> 1) ^ (~(u & 1) + 1);
236
    // copy uint32_t to int32_t
237
2.29k
    std::memcpy(v, &u, sizeof(uint32_t));
238
2.29k
    return true;
239
2.29k
}
240
241
4.49k
inline bool BitReader::GetVlqInt(uint64_t* v) {
242
4.49k
    uint64_t tmp = 0;
243
16.4k
    for (int num_bytes = 0; num_bytes < MAX_VLQ_BYTE_LEN_FOR_INT64; num_bytes++) {
244
16.4k
        uint8_t byte = 0;
245
16.4k
        if (!GetAligned<uint8_t>(1, &byte)) return false;
246
16.4k
        tmp |= static_cast<uint64_t>(byte & 0x7F) << (7 * num_bytes);
247
16.4k
        if ((byte & 0x80) == 0) {
248
4.49k
            *v = tmp;
249
4.49k
            return true;
250
4.49k
        }
251
16.4k
    }
252
0
    return false;
253
4.49k
}
254
255
4.49k
inline bool BitReader::GetZigZagVlqInt(int64_t* v) {
256
4.49k
    uint64_t u;
257
4.49k
    if (!GetVlqInt(&u)) {
258
0
        return false;
259
0
    }
260
4.49k
    u = (u >> 1) ^ (~(u & 1) + 1);
261
4.49k
    std::memcpy(v, &u, sizeof(uint64_t));
262
4.49k
    return true;
263
4.49k
}
264
265
template <typename T>
266
6.63M
int BatchedBitReader::UnpackBatch(int bit_width, int num_values, T* v) {
267
6.63M
    DCHECK(buffer_pos_ != nullptr);
268
6.63M
    DCHECK_GE(bit_width, 0);
269
6.63M
    DCHECK_LE(bit_width, MAX_BITWIDTH);
270
6.63M
    DCHECK_LE(bit_width, sizeof(T) * 8);
271
6.63M
    DCHECK_GE(num_values, 0);
272
273
6.63M
    int64_t num_read;
274
6.63M
    std::tie(buffer_pos_, num_read) =
275
6.63M
            BitPacking::UnpackValues(bit_width, buffer_pos_, bytes_left(), num_values, v);
276
6.63M
    DCHECK_LE(buffer_pos_, buffer_end_);
277
6.63M
    DCHECK_LE(num_read, num_values);
278
6.63M
    return static_cast<int>(num_read);
279
6.63M
}
_ZN5doris16BatchedBitReader11UnpackBatchIjEEiiiPT_
Line
Count
Source
266
6.53M
int BatchedBitReader::UnpackBatch(int bit_width, int num_values, T* v) {
267
6.53M
    DCHECK(buffer_pos_ != nullptr);
268
6.53M
    DCHECK_GE(bit_width, 0);
269
6.53M
    DCHECK_LE(bit_width, MAX_BITWIDTH);
270
6.53M
    DCHECK_LE(bit_width, sizeof(T) * 8);
271
6.53M
    DCHECK_GE(num_values, 0);
272
273
6.53M
    int64_t num_read;
274
6.53M
    std::tie(buffer_pos_, num_read) =
275
6.53M
            BitPacking::UnpackValues(bit_width, buffer_pos_, bytes_left(), num_values, v);
276
6.53M
    DCHECK_LE(buffer_pos_, buffer_end_);
277
    DCHECK_LE(num_read, num_values);
278
6.53M
    return static_cast<int>(num_read);
279
6.53M
}
_ZN5doris16BatchedBitReader11UnpackBatchIhEEiiiPT_
Line
Count
Source
266
94.5k
int BatchedBitReader::UnpackBatch(int bit_width, int num_values, T* v) {
267
94.5k
    DCHECK(buffer_pos_ != nullptr);
268
94.5k
    DCHECK_GE(bit_width, 0);
269
94.5k
    DCHECK_LE(bit_width, MAX_BITWIDTH);
270
94.5k
    DCHECK_LE(bit_width, sizeof(T) * 8);
271
94.5k
    DCHECK_GE(num_values, 0);
272
273
94.5k
    int64_t num_read;
274
94.5k
    std::tie(buffer_pos_, num_read) =
275
94.5k
            BitPacking::UnpackValues(bit_width, buffer_pos_, bytes_left(), num_values, v);
276
94.5k
    DCHECK_LE(buffer_pos_, buffer_end_);
277
    DCHECK_LE(num_read, num_values);
278
94.5k
    return static_cast<int>(num_read);
279
94.5k
}
280
281
148
inline bool BatchedBitReader::SkipBatch(int bit_width, int num_values_to_skip) {
282
148
    DCHECK(buffer_pos_ != nullptr);
283
148
    DCHECK_GE(bit_width, 0);
284
148
    DCHECK_LE(bit_width, MAX_BITWIDTH);
285
148
    DCHECK_GE(num_values_to_skip, 0);
286
287
148
    int skip_bytes = BitUtil::RoundUpNumBytes(bit_width * num_values_to_skip);
288
148
    if (skip_bytes > buffer_end_ - buffer_pos_) {
289
0
        return false;
290
0
    }
291
148
    buffer_pos_ += skip_bytes;
292
148
    return true;
293
148
}
294
295
template <typename T>
296
int BatchedBitReader::UnpackAndDecodeBatch(int bit_width, T* dict, int64_t dict_len, int num_values,
297
                                           T* v, int64_t stride) {
298
    DCHECK(buffer_pos_ != nullptr);
299
    DCHECK_GE(bit_width, 0);
300
    DCHECK_LE(bit_width, MAX_BITWIDTH);
301
    DCHECK_GE(num_values, 0);
302
303
    const uint8_t* new_buffer_pos;
304
    int64_t num_read;
305
    bool decode_error = false;
306
    std::tie(new_buffer_pos, num_read) =
307
            BitPacking::UnpackAndDecodeValues(bit_width, buffer_pos_, bytes_left(), dict, dict_len,
308
                                              num_values, v, stride, &decode_error);
309
    if (UNLIKELY(decode_error)) return -1;
310
    buffer_pos_ = new_buffer_pos;
311
    DCHECK_LE(buffer_pos_, buffer_end_);
312
    DCHECK_LE(num_read, num_values);
313
    return static_cast<int>(num_read);
314
}
315
316
template <typename T>
317
10.9M
bool BatchedBitReader::GetBytes(int num_bytes, T* v) {
318
10.9M
    DCHECK(buffer_pos_ != nullptr);
319
10.9M
    DCHECK_GE(num_bytes, 0);
320
10.9M
    DCHECK_LE(num_bytes, sizeof(T));
321
10.9M
    if (UNLIKELY(buffer_pos_ + num_bytes > buffer_end_)) return false;
322
10.9M
    *v = 0; // Ensure unset bytes are initialized to zero.
323
10.9M
    memcpy(v, buffer_pos_, num_bytes);
324
10.9M
    buffer_pos_ += num_bytes;
325
10.9M
    return true;
326
10.9M
}
_ZN5doris16BatchedBitReader8GetBytesIhEEbiPT_
Line
Count
Source
317
7.59M
bool BatchedBitReader::GetBytes(int num_bytes, T* v) {
318
7.59M
    DCHECK(buffer_pos_ != nullptr);
319
7.59M
    DCHECK_GE(num_bytes, 0);
320
7.59M
    DCHECK_LE(num_bytes, sizeof(T));
321
7.59M
    if (UNLIKELY(buffer_pos_ + num_bytes > buffer_end_)) return false;
322
7.59M
    *v = 0; // Ensure unset bytes are initialized to zero.
323
7.59M
    memcpy(v, buffer_pos_, num_bytes);
324
7.59M
    buffer_pos_ += num_bytes;
325
7.59M
    return true;
326
7.59M
}
_ZN5doris16BatchedBitReader8GetBytesIjEEbiPT_
Line
Count
Source
317
3.40M
bool BatchedBitReader::GetBytes(int num_bytes, T* v) {
318
3.40M
    DCHECK(buffer_pos_ != nullptr);
319
3.40M
    DCHECK_GE(num_bytes, 0);
320
3.40M
    DCHECK_LE(num_bytes, sizeof(T));
321
3.40M
    if (UNLIKELY(buffer_pos_ + num_bytes > buffer_end_)) return false;
322
3.40M
    *v = 0; // Ensure unset bytes are initialized to zero.
323
3.40M
    memcpy(v, buffer_pos_, num_bytes);
324
3.40M
    buffer_pos_ += num_bytes;
325
3.40M
    return true;
326
3.40M
}
327
328
template <typename UINT_T>
329
7.55M
bool BatchedBitReader::GetUleb128(UINT_T* v) {
330
7.55M
    static_assert(std::is_integral<UINT_T>::value, "Integral type required.");
331
7.55M
    static_assert(std::is_unsigned<UINT_T>::value, "Unsigned type required.");
332
7.55M
    static_assert(!std::is_same<UINT_T, bool>::value, "Bools are not supported.");
333
334
7.55M
    *v = 0;
335
7.55M
    int shift = 0;
336
7.55M
    uint8_t byte = 0;
337
7.59M
    do {
338
7.59M
        if (UNLIKELY(shift >= max_vlq_byte_len<UINT_T>() * 7)) return false;
339
7.59M
        if (!GetBytes(1, &byte)) return false;
340
341
        /// We need to convert 'byte' to UINT_T so that the result of the bitwise and
342
        /// operation is at least as long an integer as '*v', otherwise the shift may be too
343
        /// big and lead to undefined behaviour.
344
7.59M
        const UINT_T byte_as_UINT_T = byte;
345
7.59M
        *v |= (byte_as_UINT_T & 0x7Fu) << shift;
346
7.59M
        shift += 7;
347
7.59M
    } while ((byte & 0x80u) != 0);
348
7.55M
    return true;
349
7.55M
}
350
351
#include "common/compile_check_end.h"
352
} // namespace doris