Coverage Report

Created: 2026-09-29 05:16

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
719k
inline void BitWriter::PutValue(uint64_t v, int num_bits) {
35
719k
    DCHECK_LE(num_bits, 64);
36
    // Truncate the higher-order bits. This is necessary to
37
    // support signed values.
38
719k
    v &= ~0ULL >> (64 - num_bits);
39
40
719k
    buffered_values_ |= v << bit_offset_;
41
719k
    bit_offset_ += num_bits;
42
43
719k
    if (bit_offset_ >= 64) [[unlikely]] {
44
        // Flush buffered_values_ and write out bits of v that did not fit
45
209k
        buffer_->reserve(ALIGN_UP(byte_offset_ + 8, 8));
46
209k
        buffer_->resize(byte_offset_ + 8);
47
209k
        DCHECK_LE(byte_offset_ + 8, buffer_->capacity());
48
209k
        memcpy(buffer_->data() + byte_offset_, &buffered_values_, 8);
49
209k
        buffered_values_ = 0;
50
209k
        byte_offset_ += 8;
51
209k
        bit_offset_ -= 64;
52
209k
        buffered_values_ = BitUtil::ShiftRightZeroOnOverflow(v, (num_bits - bit_offset_));
53
209k
    }
54
719k
    DCHECK_LT(bit_offset_, 64);
55
719k
}
56
57
67.0M
inline void BitWriter::Flush(bool align) {
58
67.0M
    int num_bytes = BitUtil::Ceil(bit_offset_, 8);
59
67.0M
    buffer_->reserve(ALIGN_UP(byte_offset_ + num_bytes, 8));
60
67.0M
    buffer_->resize(byte_offset_ + num_bytes);
61
67.0M
    DCHECK_LE(byte_offset_ + num_bytes, buffer_->capacity());
62
67.0M
    memcpy(buffer_->data() + byte_offset_, &buffered_values_, num_bytes);
63
64
67.0M
    if (align) {
65
56.0M
        buffered_values_ = 0;
66
56.0M
        byte_offset_ += num_bytes;
67
56.0M
        bit_offset_ = 0;
68
56.0M
    }
69
67.0M
}
70
71
56.0M
inline uint8_t* BitWriter::GetNextBytePtr(int num_bytes) {
72
56.0M
    Flush(/* align */ true);
73
56.0M
    buffer_->reserve(ALIGN_UP(byte_offset_ + num_bytes, 8));
74
56.0M
    buffer_->resize(byte_offset_ + num_bytes);
75
56.0M
    uint8_t* ptr = buffer_->data() + byte_offset_;
76
56.0M
    byte_offset_ += num_bytes;
77
56.0M
    DCHECK_LE(byte_offset_, buffer_->capacity());
78
56.0M
    return ptr;
79
56.0M
}
80
81
template <typename T>
82
56.0M
void BitWriter::PutAligned(T val, int num_bytes) {
83
56.0M
    DCHECK_LE(num_bytes, sizeof(T));
84
56.0M
    uint8_t* ptr = GetNextBytePtr(num_bytes);
85
56.0M
    memcpy(ptr, &val, num_bytes);
86
56.0M
}
_ZN5doris9BitWriter10PutAlignedIhEEvT_i
Line
Count
Source
82
37.0M
void BitWriter::PutAligned(T val, int num_bytes) {
83
    DCHECK_LE(num_bytes, sizeof(T));
84
37.0M
    uint8_t* ptr = GetNextBytePtr(num_bytes);
85
37.0M
    memcpy(ptr, &val, num_bytes);
86
37.0M
}
_ZN5doris9BitWriter10PutAlignedImEEvT_i
Line
Count
Source
82
19.0M
void BitWriter::PutAligned(T val, int num_bytes) {
83
    DCHECK_LE(num_bytes, sizeof(T));
84
19.0M
    uint8_t* ptr = GetNextBytePtr(num_bytes);
85
19.0M
    memcpy(ptr, &val, num_bytes);
86
19.0M
}
87
88
19.0M
inline void BitWriter::PutVlqInt(int32_t v) {
89
37.0M
    while ((v & 0xFFFFFF80) != 0L) {
90
18.0M
        PutAligned<uint8_t>((v & 0x7F) | 0x80, 1);
91
18.0M
        v >>= 7;
92
18.0M
    }
93
19.0M
    PutAligned<uint8_t>(v & 0x7F, 1);
94
19.0M
}
95
96
inline BitReader::BitReader(const uint8_t* buffer, int buffer_len)
97
1.79k
        : buffer_(buffer),
98
1.79k
          max_bytes_(buffer_len),
99
1.79k
          buffered_values_(0),
100
1.79k
          byte_offset_(0),
101
1.79k
          bit_offset_(0) {
102
1.79k
    int num_bytes = std::min(8, max_bytes_);
103
1.79k
    memcpy(&buffered_values_, buffer_ + byte_offset_, num_bytes);
104
1.79k
}
105
106
273k
inline void BitReader::BufferValues() {
107
273k
    int bytes_remaining = max_bytes_ - byte_offset_;
108
273k
    if (bytes_remaining >= 8) [[likely]] {
109
272k
        memcpy(&buffered_values_, buffer_ + byte_offset_, 8);
110
272k
    } else {
111
675
        memcpy(&buffered_values_, buffer_ + byte_offset_, bytes_remaining);
112
675
    }
113
273k
}
114
115
template <typename T>
116
2.86M
bool BitReader::GetValue(int num_bits, T* v) {
117
2.86M
    DCHECK_LE(num_bits, 64);
118
2.86M
    DCHECK_LE(num_bits, sizeof(T) * 8);
119
120
2.86M
    if (byte_offset_ * 8 + bit_offset_ + num_bits > max_bytes_ * 8) [[unlikely]] {
121
0
        return false;
122
0
    }
123
124
2.86M
    *v = static_cast<T>(BitUtil::TrailingBits(buffered_values_, bit_offset_ + num_bits) >>
125
2.86M
                        bit_offset_);
126
127
2.86M
    bit_offset_ += num_bits;
128
2.86M
    if (bit_offset_ >= 64) {
129
273k
        byte_offset_ += 8;
130
273k
        bit_offset_ -= 64;
131
273k
        BufferValues();
132
        // Read bits of v that crossed into new buffered_values_
133
273k
        *v |= BitUtil::ShiftLeftZeroOnOverflow(BitUtil::TrailingBits(buffered_values_, bit_offset_),
134
273k
                                               (num_bits - bit_offset_));
135
273k
    }
136
2.86M
    DCHECK_LE(bit_offset_, 64);
137
2.86M
    return true;
138
2.86M
}
_ZN5doris9BitReader8GetValueIsEEbiPT_
Line
Count
Source
116
107
bool BitReader::GetValue(int num_bits, T* v) {
117
107
    DCHECK_LE(num_bits, 64);
118
107
    DCHECK_LE(num_bits, sizeof(T) * 8);
119
120
107
    if (byte_offset_ * 8 + bit_offset_ + num_bits > max_bytes_ * 8) [[unlikely]] {
121
0
        return false;
122
0
    }
123
124
107
    *v = static_cast<T>(BitUtil::TrailingBits(buffered_values_, bit_offset_ + num_bits) >>
125
107
                        bit_offset_);
126
127
107
    bit_offset_ += num_bits;
128
107
    if (bit_offset_ >= 64) {
129
0
        byte_offset_ += 8;
130
0
        bit_offset_ -= 64;
131
0
        BufferValues();
132
        // Read bits of v that crossed into new buffered_values_
133
0
        *v |= BitUtil::ShiftLeftZeroOnOverflow(BitUtil::TrailingBits(buffered_values_, bit_offset_),
134
0
                                               (num_bits - bit_offset_));
135
0
    }
136
    DCHECK_LE(bit_offset_, 64);
137
107
    return true;
138
107
}
_ZN5doris9BitReader8GetValueImEEbiPT_
Line
Count
Source
116
317k
bool BitReader::GetValue(int num_bits, T* v) {
117
317k
    DCHECK_LE(num_bits, 64);
118
317k
    DCHECK_LE(num_bits, sizeof(T) * 8);
119
120
317k
    if (byte_offset_ * 8 + bit_offset_ + num_bits > max_bytes_ * 8) [[unlikely]] {
121
0
        return false;
122
0
    }
123
124
317k
    *v = static_cast<T>(BitUtil::TrailingBits(buffered_values_, bit_offset_ + num_bits) >>
125
317k
                        bit_offset_);
126
127
317k
    bit_offset_ += num_bits;
128
317k
    if (bit_offset_ >= 64) {
129
40.0k
        byte_offset_ += 8;
130
40.0k
        bit_offset_ -= 64;
131
40.0k
        BufferValues();
132
        // Read bits of v that crossed into new buffered_values_
133
40.0k
        *v |= BitUtil::ShiftLeftZeroOnOverflow(BitUtil::TrailingBits(buffered_values_, bit_offset_),
134
40.0k
                                               (num_bits - bit_offset_));
135
40.0k
    }
136
    DCHECK_LE(bit_offset_, 64);
137
317k
    return true;
138
317k
}
_ZN5doris9BitReader8GetValueIiEEbiPT_
Line
Count
Source
116
1.44M
bool BitReader::GetValue(int num_bits, T* v) {
117
1.44M
    DCHECK_LE(num_bits, 64);
118
1.44M
    DCHECK_LE(num_bits, sizeof(T) * 8);
119
120
1.44M
    if (byte_offset_ * 8 + bit_offset_ + num_bits > max_bytes_ * 8) [[unlikely]] {
121
0
        return false;
122
0
    }
123
124
1.44M
    *v = static_cast<T>(BitUtil::TrailingBits(buffered_values_, bit_offset_ + num_bits) >>
125
1.44M
                        bit_offset_);
126
127
1.44M
    bit_offset_ += num_bits;
128
1.44M
    if (bit_offset_ >= 64) {
129
264
        byte_offset_ += 8;
130
264
        bit_offset_ -= 64;
131
264
        BufferValues();
132
        // Read bits of v that crossed into new buffered_values_
133
264
        *v |= BitUtil::ShiftLeftZeroOnOverflow(BitUtil::TrailingBits(buffered_values_, bit_offset_),
134
264
                                               (num_bits - bit_offset_));
135
264
    }
136
    DCHECK_LE(bit_offset_, 64);
137
1.44M
    return true;
138
1.44M
}
_ZN5doris9BitReader8GetValueIbEEbiPT_
Line
Count
Source
116
285k
bool BitReader::GetValue(int num_bits, T* v) {
117
285k
    DCHECK_LE(num_bits, 64);
118
285k
    DCHECK_LE(num_bits, sizeof(T) * 8);
119
120
285k
    if (byte_offset_ * 8 + bit_offset_ + num_bits > max_bytes_ * 8) [[unlikely]] {
121
0
        return false;
122
0
    }
123
124
285k
    *v = static_cast<T>(BitUtil::TrailingBits(buffered_values_, bit_offset_ + num_bits) >>
125
285k
                        bit_offset_);
126
127
285k
    bit_offset_ += num_bits;
128
285k
    if (bit_offset_ >= 64) {
129
3.77k
        byte_offset_ += 8;
130
3.77k
        bit_offset_ -= 64;
131
3.77k
        BufferValues();
132
        // Read bits of v that crossed into new buffered_values_
133
3.77k
        *v |= BitUtil::ShiftLeftZeroOnOverflow(BitUtil::TrailingBits(buffered_values_, bit_offset_),
134
3.77k
                                               (num_bits - bit_offset_));
135
3.77k
    }
136
    DCHECK_LE(bit_offset_, 64);
137
285k
    return true;
138
285k
}
_ZN5doris9BitReader8GetValueIhEEbiPT_
Line
Count
Source
116
503
bool BitReader::GetValue(int num_bits, T* v) {
117
503
    DCHECK_LE(num_bits, 64);
118
503
    DCHECK_LE(num_bits, sizeof(T) * 8);
119
120
503
    if (byte_offset_ * 8 + bit_offset_ + num_bits > max_bytes_ * 8) [[unlikely]] {
121
0
        return false;
122
0
    }
123
124
503
    *v = static_cast<T>(BitUtil::TrailingBits(buffered_values_, bit_offset_ + num_bits) >>
125
503
                        bit_offset_);
126
127
503
    bit_offset_ += num_bits;
128
503
    if (bit_offset_ >= 64) {
129
5
        byte_offset_ += 8;
130
5
        bit_offset_ -= 64;
131
5
        BufferValues();
132
        // Read bits of v that crossed into new buffered_values_
133
5
        *v |= BitUtil::ShiftLeftZeroOnOverflow(BitUtil::TrailingBits(buffered_values_, bit_offset_),
134
5
                                               (num_bits - bit_offset_));
135
5
    }
136
    DCHECK_LE(bit_offset_, 64);
137
503
    return true;
138
503
}
_ZN5doris9BitReader8GetValueIlEEbiPT_
Line
Count
Source
116
286k
bool BitReader::GetValue(int num_bits, T* v) {
117
286k
    DCHECK_LE(num_bits, 64);
118
286k
    DCHECK_LE(num_bits, sizeof(T) * 8);
119
120
286k
    if (byte_offset_ * 8 + bit_offset_ + num_bits > max_bytes_ * 8) [[unlikely]] {
121
0
        return false;
122
0
    }
123
124
286k
    *v = static_cast<T>(BitUtil::TrailingBits(buffered_values_, bit_offset_ + num_bits) >>
125
286k
                        bit_offset_);
126
127
286k
    bit_offset_ += num_bits;
128
286k
    if (bit_offset_ >= 64) {
129
162k
        byte_offset_ += 8;
130
162k
        bit_offset_ -= 64;
131
162k
        BufferValues();
132
        // Read bits of v that crossed into new buffered_values_
133
162k
        *v |= BitUtil::ShiftLeftZeroOnOverflow(BitUtil::TrailingBits(buffered_values_, bit_offset_),
134
162k
                                               (num_bits - bit_offset_));
135
162k
    }
136
    DCHECK_LE(bit_offset_, 64);
137
286k
    return true;
138
286k
}
_ZN5doris9BitReader8GetValueIjEEbiPT_
Line
Count
Source
116
3
bool BitReader::GetValue(int num_bits, T* v) {
117
3
    DCHECK_LE(num_bits, 64);
118
3
    DCHECK_LE(num_bits, sizeof(T) * 8);
119
120
3
    if (byte_offset_ * 8 + bit_offset_ + num_bits > max_bytes_ * 8) [[unlikely]] {
121
0
        return false;
122
0
    }
123
124
3
    *v = static_cast<T>(BitUtil::TrailingBits(buffered_values_, bit_offset_ + num_bits) >>
125
3
                        bit_offset_);
126
127
3
    bit_offset_ += num_bits;
128
3
    if (bit_offset_ >= 64) {
129
1
        byte_offset_ += 8;
130
1
        bit_offset_ -= 64;
131
1
        BufferValues();
132
        // Read bits of v that crossed into new buffered_values_
133
1
        *v |= BitUtil::ShiftLeftZeroOnOverflow(BitUtil::TrailingBits(buffered_values_, bit_offset_),
134
1
                                               (num_bits - bit_offset_));
135
1
    }
136
    DCHECK_LE(bit_offset_, 64);
137
3
    return true;
138
3
}
_ZN5doris9BitReader8GetValueIcEEbiPT_
Line
Count
Source
116
529k
bool BitReader::GetValue(int num_bits, T* v) {
117
529k
    DCHECK_LE(num_bits, 64);
118
529k
    DCHECK_LE(num_bits, sizeof(T) * 8);
119
120
529k
    if (byte_offset_ * 8 + bit_offset_ + num_bits > max_bytes_ * 8) [[unlikely]] {
121
0
        return false;
122
0
    }
123
124
529k
    *v = static_cast<T>(BitUtil::TrailingBits(buffered_values_, bit_offset_ + num_bits) >>
125
529k
                        bit_offset_);
126
127
529k
    bit_offset_ += num_bits;
128
529k
    if (bit_offset_ >= 64) {
129
66.1k
        byte_offset_ += 8;
130
66.1k
        bit_offset_ -= 64;
131
66.1k
        BufferValues();
132
        // Read bits of v that crossed into new buffered_values_
133
66.1k
        *v |= BitUtil::ShiftLeftZeroOnOverflow(BitUtil::TrailingBits(buffered_values_, bit_offset_),
134
66.1k
                                               (num_bits - bit_offset_));
135
66.1k
    }
136
    DCHECK_LE(bit_offset_, 64);
137
529k
    return true;
138
529k
}
139
140
89.5k
inline void BitReader::Rewind(int num_bits) {
141
89.5k
    bit_offset_ -= num_bits;
142
89.5k
    if (bit_offset_ >= 0) {
143
88.3k
        return;
144
88.3k
    }
145
2.25k
    while (bit_offset_ < 0) {
146
1.12k
        int seek_back = std::min(byte_offset_, 8);
147
1.12k
        byte_offset_ -= seek_back;
148
1.12k
        bit_offset_ += seek_back * 8;
149
1.12k
    }
150
    // This should only be executed *if* rewinding by 'num_bits'
151
    // make the existing buffered_values_ invalid
152
1.12k
    DCHECK_GE(byte_offset_, 0); // Check for underflow
153
1.12k
    memcpy(&buffered_values_, buffer_ + byte_offset_, 8);
154
1.12k
}
155
156
80
inline bool BitReader::Advance(int64_t num_bits) {
157
80
    int64_t bits_required = bit_offset_ + num_bits;
158
80
    int64_t bytes_required = (bits_required >> 3) + ((bits_required & 7) != 0);
159
80
    if (bytes_required > max_bytes_ - byte_offset_) {
160
0
        return false;
161
0
    }
162
80
    byte_offset_ += static_cast<int>(bits_required >> 3);
163
80
    bit_offset_ = static_cast<int>(bits_required & 7);
164
80
    BufferValues();
165
80
    return true;
166
80
}
167
168
2
inline void BitReader::SeekToBit(unsigned int stream_position) {
169
2
    DCHECK_LE(stream_position, max_bytes_ * 8);
170
171
2
    int delta = static_cast<int>(stream_position) - position();
172
2
    if (delta == 0) {
173
0
        return;
174
2
    } else if (delta < 0) {
175
1
        Rewind(position() - stream_position);
176
1
    } else {
177
1
        bit_offset_ += delta;
178
1
        while (bit_offset_ >= 64) {
179
0
            byte_offset_ += 8;
180
0
            bit_offset_ -= 64;
181
0
            if (bit_offset_ < 64) {
182
                // This should only be executed if seeking to
183
                // 'stream_position' makes the existing buffered_values_
184
                // invalid.
185
0
                BufferValues();
186
0
            }
187
0
        }
188
1
    }
189
2
}
190
191
template <typename T>
192
71.3k
bool BitReader::GetAligned(int num_bytes, T* v) {
193
71.3k
    DCHECK_LE(num_bytes, sizeof(T));
194
71.3k
    int bytes_read = BitUtil::Ceil(bit_offset_, 8);
195
71.3k
    if (byte_offset_ + bytes_read + num_bytes > max_bytes_) [[unlikely]] {
196
315
        return false;
197
315
    }
198
199
    // Advance byte_offset to next unread byte and read num_bytes
200
71.0k
    byte_offset_ += bytes_read;
201
71.0k
    memcpy(v, buffer_ + byte_offset_, num_bytes);
202
71.0k
    byte_offset_ += num_bytes;
203
204
    // Reset buffered_values_
205
71.0k
    bit_offset_ = 0;
206
71.0k
    int bytes_remaining = max_bytes_ - byte_offset_;
207
71.0k
    if (bytes_remaining >= 8) [[likely]] {
208
66.6k
        memcpy(&buffered_values_, buffer_ + byte_offset_, 8);
209
66.6k
    } else {
210
4.47k
        memcpy(&buffered_values_, buffer_ + byte_offset_, bytes_remaining);
211
4.47k
    }
212
71.0k
    return true;
213
71.3k
}
_ZN5doris9BitReader10GetAlignedIhEEbiPT_
Line
Count
Source
192
46.5k
bool BitReader::GetAligned(int num_bytes, T* v) {
193
46.5k
    DCHECK_LE(num_bytes, sizeof(T));
194
46.5k
    int bytes_read = BitUtil::Ceil(bit_offset_, 8);
195
46.5k
    if (byte_offset_ + bytes_read + num_bytes > max_bytes_) [[unlikely]] {
196
315
        return false;
197
315
    }
198
199
    // Advance byte_offset to next unread byte and read num_bytes
200
46.2k
    byte_offset_ += bytes_read;
201
46.2k
    memcpy(v, buffer_ + byte_offset_, num_bytes);
202
46.2k
    byte_offset_ += num_bytes;
203
204
    // Reset buffered_values_
205
46.2k
    bit_offset_ = 0;
206
46.2k
    int bytes_remaining = max_bytes_ - byte_offset_;
207
46.2k
    if (bytes_remaining >= 8) [[likely]] {
208
43.6k
        memcpy(&buffered_values_, buffer_ + byte_offset_, 8);
209
43.6k
    } else {
210
2.63k
        memcpy(&buffered_values_, buffer_ + byte_offset_, bytes_remaining);
211
2.63k
    }
212
46.2k
    return true;
213
46.5k
}
_ZN5doris9BitReader10GetAlignedIsEEbiPT_
Line
Count
Source
192
124
bool BitReader::GetAligned(int num_bytes, T* v) {
193
124
    DCHECK_LE(num_bytes, sizeof(T));
194
124
    int bytes_read = BitUtil::Ceil(bit_offset_, 8);
195
124
    if (byte_offset_ + bytes_read + num_bytes > max_bytes_) [[unlikely]] {
196
0
        return false;
197
0
    }
198
199
    // Advance byte_offset to next unread byte and read num_bytes
200
124
    byte_offset_ += bytes_read;
201
124
    memcpy(v, buffer_ + byte_offset_, num_bytes);
202
124
    byte_offset_ += num_bytes;
203
204
    // Reset buffered_values_
205
124
    bit_offset_ = 0;
206
124
    int bytes_remaining = max_bytes_ - byte_offset_;
207
124
    if (bytes_remaining >= 8) [[likely]] {
208
0
        memcpy(&buffered_values_, buffer_ + byte_offset_, 8);
209
124
    } else {
210
124
        memcpy(&buffered_values_, buffer_ + byte_offset_, bytes_remaining);
211
124
    }
212
124
    return true;
213
124
}
_ZN5doris9BitReader10GetAlignedIbEEbiPT_
Line
Count
Source
192
22.7k
bool BitReader::GetAligned(int num_bytes, T* v) {
193
22.7k
    DCHECK_LE(num_bytes, sizeof(T));
194
22.7k
    int bytes_read = BitUtil::Ceil(bit_offset_, 8);
195
22.7k
    if (byte_offset_ + bytes_read + num_bytes > max_bytes_) [[unlikely]] {
196
0
        return false;
197
0
    }
198
199
    // Advance byte_offset to next unread byte and read num_bytes
200
22.7k
    byte_offset_ += bytes_read;
201
22.7k
    memcpy(v, buffer_ + byte_offset_, num_bytes);
202
22.7k
    byte_offset_ += num_bytes;
203
204
    // Reset buffered_values_
205
22.7k
    bit_offset_ = 0;
206
22.7k
    int bytes_remaining = max_bytes_ - byte_offset_;
207
22.7k
    if (bytes_remaining >= 8) [[likely]] {
208
21.3k
        memcpy(&buffered_values_, buffer_ + byte_offset_, 8);
209
21.3k
    } else {
210
1.38k
        memcpy(&buffered_values_, buffer_ + byte_offset_, bytes_remaining);
211
1.38k
    }
212
22.7k
    return true;
213
22.7k
}
_ZN5doris9BitReader10GetAlignedImEEbiPT_
Line
Count
Source
192
1.94k
bool BitReader::GetAligned(int num_bytes, T* v) {
193
1.94k
    DCHECK_LE(num_bytes, sizeof(T));
194
1.94k
    int bytes_read = BitUtil::Ceil(bit_offset_, 8);
195
1.94k
    if (byte_offset_ + bytes_read + num_bytes > max_bytes_) [[unlikely]] {
196
0
        return false;
197
0
    }
198
199
    // Advance byte_offset to next unread byte and read num_bytes
200
1.94k
    byte_offset_ += bytes_read;
201
1.94k
    memcpy(v, buffer_ + byte_offset_, num_bytes);
202
1.94k
    byte_offset_ += num_bytes;
203
204
    // Reset buffered_values_
205
1.94k
    bit_offset_ = 0;
206
1.94k
    int bytes_remaining = max_bytes_ - byte_offset_;
207
1.94k
    if (bytes_remaining >= 8) [[likely]] {
208
1.61k
        memcpy(&buffered_values_, buffer_ + byte_offset_, 8);
209
1.61k
    } else {
210
330
        memcpy(&buffered_values_, buffer_ + byte_offset_, bytes_remaining);
211
330
    }
212
1.94k
    return true;
213
1.94k
}
214
215
33.2k
inline bool BitReader::GetVlqInt(uint32_t* v) {
216
33.2k
    uint32_t tmp = 0;
217
33.9k
    for (int num_bytes = 0; num_bytes < MAX_VLQ_BYTE_LEN; num_bytes++) {
218
33.9k
        uint8_t byte = 0;
219
33.9k
        if (!GetAligned<uint8_t>(1, &byte)) return false;
220
33.6k
        tmp |= static_cast<uint32_t>(byte & 0x7F) << (7 * num_bytes);
221
33.6k
        if ((byte & 0x80) == 0) {
222
32.9k
            *v = tmp;
223
32.9k
            return true;
224
32.9k
        }
225
33.6k
    }
226
0
    return false;
227
33.2k
}
228
229
3.23k
inline bool BitReader::GetZigZagVlqInt(int32_t* v) {
230
3.23k
    uint32_t u;
231
3.23k
    if (!GetVlqInt(&u)) {
232
3
        return false;
233
3
    }
234
3.22k
    u = (u >> 1) ^ (~(u & 1) + 1);
235
    // copy uint32_t to int32_t
236
3.22k
    std::memcpy(v, &u, sizeof(uint32_t));
237
3.22k
    return true;
238
3.23k
}
239
240
0
inline bool BitReader::GetVlqInt(uint64_t* v) {
241
0
    uint64_t tmp = 0;
242
0
    for (int num_bytes = 0; num_bytes < MAX_VLQ_BYTE_LEN_FOR_INT64; num_bytes++) {
243
0
        uint8_t byte = 0;
244
0
        if (!GetAligned<uint8_t>(1, &byte)) return false;
245
0
        tmp |= static_cast<uint64_t>(byte & 0x7F) << (7 * num_bytes);
246
0
        if ((byte & 0x80) == 0) {
247
0
            *v = tmp;
248
0
            return true;
249
0
        }
250
0
    }
251
0
    return false;
252
0
}
253
254
0
inline bool BitReader::GetZigZagVlqInt(int64_t* v) {
255
0
    uint64_t u;
256
0
    if (!GetVlqInt(&u)) {
257
0
        return false;
258
0
    }
259
0
    u = (u >> 1) ^ (~(u & 1) + 1);
260
0
    std::memcpy(v, &u, sizeof(uint64_t));
261
0
    return true;
262
0
}
263
264
template <typename T>
265
670
int BatchedBitReader::UnpackBatch(int bit_width, int num_values, T* v) {
266
670
    DCHECK(buffer_pos_ != nullptr);
267
670
    DCHECK_GE(bit_width, 0);
268
670
    DCHECK_LE(bit_width, MAX_BITWIDTH);
269
670
    DCHECK_LE(bit_width, sizeof(T) * 8);
270
670
    DCHECK_GE(num_values, 0);
271
272
670
    int64_t num_read;
273
670
    std::tie(buffer_pos_, num_read) =
274
670
            BitPacking::UnpackValues(bit_width, buffer_pos_, bytes_left(), num_values, v);
275
670
    DCHECK_LE(buffer_pos_, buffer_end_);
276
670
    DCHECK_LE(num_read, num_values);
277
670
    return static_cast<int>(num_read);
278
670
}
_ZN5doris16BatchedBitReader11UnpackBatchIhEEiiiPT_
Line
Count
Source
265
25
int BatchedBitReader::UnpackBatch(int bit_width, int num_values, T* v) {
266
25
    DCHECK(buffer_pos_ != nullptr);
267
25
    DCHECK_GE(bit_width, 0);
268
25
    DCHECK_LE(bit_width, MAX_BITWIDTH);
269
25
    DCHECK_LE(bit_width, sizeof(T) * 8);
270
25
    DCHECK_GE(num_values, 0);
271
272
25
    int64_t num_read;
273
25
    std::tie(buffer_pos_, num_read) =
274
25
            BitPacking::UnpackValues(bit_width, buffer_pos_, bytes_left(), num_values, v);
275
25
    DCHECK_LE(buffer_pos_, buffer_end_);
276
    DCHECK_LE(num_read, num_values);
277
25
    return static_cast<int>(num_read);
278
25
}
_ZN5doris16BatchedBitReader11UnpackBatchIjEEiiiPT_
Line
Count
Source
265
511
int BatchedBitReader::UnpackBatch(int bit_width, int num_values, T* v) {
266
511
    DCHECK(buffer_pos_ != nullptr);
267
511
    DCHECK_GE(bit_width, 0);
268
511
    DCHECK_LE(bit_width, MAX_BITWIDTH);
269
511
    DCHECK_LE(bit_width, sizeof(T) * 8);
270
511
    DCHECK_GE(num_values, 0);
271
272
511
    int64_t num_read;
273
511
    std::tie(buffer_pos_, num_read) =
274
511
            BitPacking::UnpackValues(bit_width, buffer_pos_, bytes_left(), num_values, v);
275
511
    DCHECK_LE(buffer_pos_, buffer_end_);
276
    DCHECK_LE(num_read, num_values);
277
511
    return static_cast<int>(num_read);
278
511
}
_ZN5doris16BatchedBitReader11UnpackBatchItEEiiiPT_
Line
Count
Source
265
134
int BatchedBitReader::UnpackBatch(int bit_width, int num_values, T* v) {
266
134
    DCHECK(buffer_pos_ != nullptr);
267
134
    DCHECK_GE(bit_width, 0);
268
134
    DCHECK_LE(bit_width, MAX_BITWIDTH);
269
134
    DCHECK_LE(bit_width, sizeof(T) * 8);
270
134
    DCHECK_GE(num_values, 0);
271
272
134
    int64_t num_read;
273
134
    std::tie(buffer_pos_, num_read) =
274
134
            BitPacking::UnpackValues(bit_width, buffer_pos_, bytes_left(), num_values, v);
275
134
    DCHECK_LE(buffer_pos_, buffer_end_);
276
    DCHECK_LE(num_read, num_values);
277
134
    return static_cast<int>(num_read);
278
134
}
279
280
0
inline bool BatchedBitReader::SkipBatch(int bit_width, int num_values_to_skip) {
281
0
    DCHECK(buffer_pos_ != nullptr);
282
0
    DCHECK_GE(bit_width, 0);
283
0
    DCHECK_LE(bit_width, MAX_BITWIDTH);
284
0
    DCHECK_GE(num_values_to_skip, 0);
285
286
0
    int skip_bytes = BitUtil::RoundUpNumBytes(bit_width * num_values_to_skip);
287
0
    if (skip_bytes > buffer_end_ - buffer_pos_) {
288
0
        return false;
289
0
    }
290
0
    buffer_pos_ += skip_bytes;
291
0
    return true;
292
0
}
293
294
template <typename T>
295
int BatchedBitReader::UnpackAndDecodeBatch(int bit_width, T* dict, int64_t dict_len, int num_values,
296
                                           T* v, int64_t stride) {
297
    DCHECK(buffer_pos_ != nullptr);
298
    DCHECK_GE(bit_width, 0);
299
    DCHECK_LE(bit_width, MAX_BITWIDTH);
300
    DCHECK_GE(num_values, 0);
301
302
    const uint8_t* new_buffer_pos;
303
    int64_t num_read;
304
    bool decode_error = false;
305
    std::tie(new_buffer_pos, num_read) =
306
            BitPacking::UnpackAndDecodeValues(bit_width, buffer_pos_, bytes_left(), dict, dict_len,
307
                                              num_values, v, stride, &decode_error);
308
    if (UNLIKELY(decode_error)) return -1;
309
    buffer_pos_ = new_buffer_pos;
310
    DCHECK_LE(buffer_pos_, buffer_end_);
311
    DCHECK_LE(num_read, num_values);
312
    return static_cast<int>(num_read);
313
}
314
315
template <typename T>
316
1.72k
bool BatchedBitReader::GetBytes(int num_bytes, T* v) {
317
1.72k
    DCHECK(buffer_pos_ != nullptr);
318
1.72k
    DCHECK_GE(num_bytes, 0);
319
1.72k
    DCHECK_LE(num_bytes, sizeof(T));
320
1.72k
    if (UNLIKELY(buffer_pos_ + num_bytes > buffer_end_)) return false;
321
1.71k
    *v = 0; // Ensure unset bytes are initialized to zero.
322
1.71k
    memcpy(v, buffer_pos_, num_bytes);
323
1.71k
    buffer_pos_ += num_bytes;
324
1.71k
    return true;
325
1.72k
}
_ZN5doris16BatchedBitReader8GetBytesIhEEbiPT_
Line
Count
Source
316
1.23k
bool BatchedBitReader::GetBytes(int num_bytes, T* v) {
317
1.23k
    DCHECK(buffer_pos_ != nullptr);
318
1.23k
    DCHECK_GE(num_bytes, 0);
319
1.23k
    DCHECK_LE(num_bytes, sizeof(T));
320
1.23k
    if (UNLIKELY(buffer_pos_ + num_bytes > buffer_end_)) return false;
321
1.23k
    *v = 0; // Ensure unset bytes are initialized to zero.
322
1.23k
    memcpy(v, buffer_pos_, num_bytes);
323
1.23k
    buffer_pos_ += num_bytes;
324
1.23k
    return true;
325
1.23k
}
_ZN5doris16BatchedBitReader8GetBytesIjEEbiPT_
Line
Count
Source
316
254
bool BatchedBitReader::GetBytes(int num_bytes, T* v) {
317
254
    DCHECK(buffer_pos_ != nullptr);
318
254
    DCHECK_GE(num_bytes, 0);
319
254
    DCHECK_LE(num_bytes, sizeof(T));
320
254
    if (UNLIKELY(buffer_pos_ + num_bytes > buffer_end_)) return false;
321
254
    *v = 0; // Ensure unset bytes are initialized to zero.
322
254
    memcpy(v, buffer_pos_, num_bytes);
323
254
    buffer_pos_ += num_bytes;
324
254
    return true;
325
254
}
_ZN5doris16BatchedBitReader8GetBytesItEEbiPT_
Line
Count
Source
316
229
bool BatchedBitReader::GetBytes(int num_bytes, T* v) {
317
229
    DCHECK(buffer_pos_ != nullptr);
318
229
    DCHECK_GE(num_bytes, 0);
319
229
    DCHECK_LE(num_bytes, sizeof(T));
320
229
    if (UNLIKELY(buffer_pos_ + num_bytes > buffer_end_)) return false;
321
229
    *v = 0; // Ensure unset bytes are initialized to zero.
322
229
    memcpy(v, buffer_pos_, num_bytes);
323
229
    buffer_pos_ += num_bytes;
324
229
    return true;
325
229
}
326
327
template <typename UINT_T>
328
1.07k
bool BatchedBitReader::GetUleb128(UINT_T* v) {
329
1.07k
    static_assert(std::is_integral<UINT_T>::value, "Integral type required.");
330
1.07k
    static_assert(std::is_unsigned<UINT_T>::value, "Unsigned type required.");
331
1.07k
    static_assert(!std::is_same<UINT_T, bool>::value, "Bools are not supported.");
332
333
1.07k
    *v = 0;
334
1.07k
    int shift = 0;
335
1.07k
    uint8_t byte = 0;
336
1.23k
    do {
337
1.23k
        if (UNLIKELY(shift >= max_vlq_byte_len<UINT_T>() * 7)) return false;
338
1.23k
        if (!GetBytes(1, &byte)) return false;
339
340
        /// We need to convert 'byte' to UINT_T so that the result of the bitwise and
341
        /// operation is at least as long an integer as '*v', otherwise the shift may be too
342
        /// big and lead to undefined behaviour.
343
1.23k
        const UINT_T byte_as_UINT_T = byte;
344
1.23k
        *v |= (byte_as_UINT_T & 0x7Fu) << shift;
345
1.23k
        shift += 7;
346
1.23k
    } while ((byte & 0x80u) != 0);
347
1.07k
    return true;
348
1.07k
}
349
350
} // namespace doris