Coverage Report

Created: 2025-07-25 13:35

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/root/doris/be/src/util/coding.h
Line
Count
Source
1
//  Copyright (c) 2011-present, Facebook, Inc.  All rights reserved.
2
//  This source code is licensed under both the GPLv2 (found in the
3
//  COPYING file in the root directory) and Apache 2.0 License
4
//  (found in the LICENSE.Apache file in the root directory).
5
// Copyright (c) 2011 The LevelDB Authors. All rights reserved.
6
// Use of this source code is governed by a BSD-style license that can be
7
// found in the LICENSE file. See the AUTHORS file for names of contributors.
8
9
#pragma once
10
11
#include <bit>
12
#ifndef __APPLE__
13
#include <endian.h>
14
#endif
15
#include <stdint.h>
16
#include <string.h>
17
18
#include "olap/olap_common.h"
19
#include "util/slice.h"
20
21
namespace doris {
22
23
// TODO(zc): add encode big endian later when we need it
24
// use big endian when we have order requirement.
25
// little endian is more efficient when we use X86 CPU, so
26
// when we have no order needs, we prefer little endian encoding
27
inline void encode_fixed8(uint8_t* buf, uint8_t val) {
28
    *buf = val;
29
}
30
31
550k
inline void encode_fixed16_le(uint8_t* buf, uint16_t val) {
32
550k
    val = to_endian<std::endian::little>(val);
33
550k
    memcpy(buf, &val, sizeof(val));
34
550k
}
35
36
122M
inline void encode_fixed32_le(uint8_t* buf, uint32_t val) {
37
122M
    val = to_endian<std::endian::little>(val);
38
122M
    memcpy(buf, &val, sizeof(val));
39
122M
}
40
41
504k
inline void encode_fixed64_le(uint8_t* buf, uint64_t val) {
42
504k
    val = to_endian<std::endian::little>(val);
43
504k
    memcpy(buf, &val, sizeof(val));
44
504k
}
45
46
48.8k
inline void encode_fixed128_le(uint8_t* buf, uint128_t val) {
47
48.8k
    val = to_endian<std::endian::little>(val);
48
48.8k
    memcpy(buf, &val, sizeof(val));
49
48.8k
}
50
51
7.15M
inline uint8_t decode_fixed8(const uint8_t* buf) {
52
7.15M
    return *buf;
53
7.15M
}
54
55
646k
inline uint16_t decode_fixed16_le(const uint8_t* buf) {
56
646k
    uint16_t res;
57
646k
    memcpy(&res, buf, sizeof(res));
58
646k
    return to_endian<std::endian::little>(res);
59
646k
}
60
61
295M
inline uint32_t decode_fixed32_le(const uint8_t* buf) {
62
295M
    uint32_t res;
63
295M
    memcpy(&res, buf, sizeof(res));
64
295M
    return to_endian<std::endian::little>(res);
65
295M
}
66
67
3.92G
inline uint64_t decode_fixed64_le(const uint8_t* buf) {
68
3.92G
    uint64_t res;
69
3.92G
    memcpy(&res, buf, sizeof(res));
70
3.92G
    return to_endian<std::endian::little>(res);
71
3.92G
}
72
73
48.8k
inline uint128_t decode_fixed128_le(const uint8_t* buf) {
74
48.8k
    uint128_t res;
75
48.8k
    memcpy(&res, buf, sizeof(res));
76
48.8k
    return to_endian<std::endian::little>(res);
77
48.8k
}
78
79
template <typename T>
80
108M
void put_fixed32_le(T* dst, uint32_t val) {
81
108M
    uint8_t buf[sizeof(val)];
82
108M
    encode_fixed32_le(buf, val);
83
108M
    dst->append((char*)buf, sizeof(buf));
84
108M
}
_ZN5doris14put_fixed32_leINS_10faststringEEEvPT_j
Line
Count
Source
80
103M
void put_fixed32_le(T* dst, uint32_t val) {
81
103M
    uint8_t buf[sizeof(val)];
82
103M
    encode_fixed32_le(buf, val);
83
103M
    dst->append((char*)buf, sizeof(buf));
84
103M
}
_ZN5doris14put_fixed32_leINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEvPT_j
Line
Count
Source
80
4.73M
void put_fixed32_le(T* dst, uint32_t val) {
81
4.73M
    uint8_t buf[sizeof(val)];
82
4.73M
    encode_fixed32_le(buf, val);
83
4.73M
    dst->append((char*)buf, sizeof(buf));
84
4.73M
}
85
86
template <typename T>
87
62.5k
void put_fixed64_le(T* dst, uint64_t val) {
88
62.5k
    uint8_t buf[sizeof(val)];
89
62.5k
    encode_fixed64_le(buf, val);
90
62.5k
    dst->append((char*)buf, sizeof(buf));
91
62.5k
}
_ZN5doris14put_fixed64_leINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEvPT_m
Line
Count
Source
87
13.6k
void put_fixed64_le(T* dst, uint64_t val) {
88
13.6k
    uint8_t buf[sizeof(val)];
89
13.6k
    encode_fixed64_le(buf, val);
90
13.6k
    dst->append((char*)buf, sizeof(buf));
91
13.6k
}
_ZN5doris14put_fixed64_leINS_10faststringEEEvPT_m
Line
Count
Source
87
48.9k
void put_fixed64_le(T* dst, uint64_t val) {
88
48.9k
    uint8_t buf[sizeof(val)];
89
48.9k
    encode_fixed64_le(buf, val);
90
48.9k
    dst->append((char*)buf, sizeof(buf));
91
48.9k
}
92
93
// Returns the length of the varint32 or varint64 encoding of "v"
94
70
inline int varint_length(uint64_t v) {
95
70
    int len = 1;
96
70
    while (v >= 128) {
97
0
        v >>= 7;
98
0
        len++;
99
0
    }
100
70
    return len;
101
70
}
102
103
template <typename T>
104
48.8k
void put_fixed128_le(T* dst, uint128_t val) {
105
48.8k
    uint8_t buf[sizeof(val)];
106
48.8k
    encode_fixed128_le(buf, val);
107
48.8k
    dst->append((char*)buf, sizeof(buf));
108
48.8k
}
109
110
extern uint8_t* encode_varint32(uint8_t* dst, uint32_t value);
111
extern uint8_t* encode_varint64(uint8_t* dst, uint64_t value);
112
113
4.00M
inline uint8_t* encode_varint64(uint8_t* dst, uint64_t v) {
114
4.00M
    static const unsigned int B = 128;
115
9.03M
    while (v >= B) {
116
        // Fetch low seven bits from current v, and the eight bit is marked as compression mark.
117
        // v | B is optimised from (v & (B-1)) | B, because result is assigned to uint8_t and other bits
118
        // is cleared by implicit conversion.
119
5.03M
        *(dst++) = v | B;
120
5.03M
        v >>= 7;
121
5.03M
    }
122
4.00M
    *(dst++) = static_cast<unsigned char>(v);
123
4.00M
    return dst;
124
4.00M
}
125
126
extern const uint8_t* decode_varint32_ptr_fallback(const uint8_t* p, const uint8_t* limit,
127
                                                   uint32_t* value);
128
129
inline const uint8_t* decode_varint32_ptr(const uint8_t* ptr, const uint8_t* limit,
130
245M
                                          uint32_t* value) {
131
245M
    if (ptr < limit) {
132
245M
        uint32_t result = *ptr;
133
245M
        if ((result & 128) == 0) {
134
245M
            *value = result;
135
245M
            return ptr + 1;
136
245M
        }
137
245M
    }
138
257k
    return decode_varint32_ptr_fallback(ptr, limit, value);
139
245M
}
140
141
extern const uint8_t* decode_varint64_ptr(const uint8_t* p, const uint8_t* limit, uint64_t* value);
142
143
template <typename T>
144
67.0M
void put_varint32(T* dst, uint32_t v) {
145
67.0M
    uint8_t buf[16];
146
67.0M
    uint8_t* ptr = encode_varint32(buf, v);
147
67.0M
    dst->append((char*)buf, static_cast<size_t>(ptr - buf));
148
67.0M
}
149
150
template <typename T>
151
void put_varint64(T* dst, uint64_t v) {
152
    uint8_t buf[16];
153
    uint8_t* ptr = encode_varint64(buf, v);
154
    dst->append((char*)buf, static_cast<size_t>(ptr - buf));
155
}
156
157
template <typename T>
158
4.00M
void put_length_prefixed_slice(T* dst, const Slice& value) {
159
4.00M
    put_varint32(dst, value.get_size());
160
4.00M
    dst->append(value.get_data(), value.get_size());
161
4.00M
}
162
163
template <typename T>
164
4.00M
void put_varint64_varint32(T* dst, uint64_t v1, uint32_t v2) {
165
4.00M
    uint8_t buf[16];
166
4.00M
    uint8_t* ptr = encode_varint64(buf, v1);
167
4.00M
    ptr = encode_varint32(ptr, v2);
168
4.00M
    dst->append((char*)buf, static_cast<size_t>(ptr - buf));
169
4.00M
}
170
171
// parse a varint32 from the start of `input` into `val`.
172
// on success, return true and advance `input` past the parsed value.
173
// on failure, return false and `input` is not modified.
174
1.06M
inline bool get_varint32(Slice* input, uint32_t* val) {
175
1.06M
    const uint8_t* p = (const uint8_t*)input->data;
176
1.06M
    const uint8_t* limit = p + input->size;
177
1.06M
    const uint8_t* q = decode_varint32_ptr(p, limit, val);
178
1.06M
    if (q == nullptr) {
179
0
        return false;
180
1.06M
    } else {
181
1.06M
        *input = Slice(q, limit - q);
182
1.06M
        return true;
183
1.06M
    }
184
1.06M
}
185
186
// parse a varint64 from the start of `input` into `val`.
187
// on success, return true and advance `input` past the parsed value.
188
// on failure, return false and `input` is not modified.
189
401k
inline bool get_varint64(Slice* input, uint64_t* val) {
190
401k
    const uint8_t* p = (const uint8_t*)input->data;
191
401k
    const uint8_t* limit = p + input->size;
192
401k
    const uint8_t* q = decode_varint64_ptr(p, limit, val);
193
401k
    if (q == nullptr) {
194
0
        return false;
195
401k
    } else {
196
401k
        *input = Slice(q, limit - q);
197
401k
        return true;
198
401k
    }
199
401k
}
200
201
// parse a length-prefixed-slice from the start of `input` into `val`.
202
// on success, return true and advance `input` past the parsed value.
203
// on failure, return false and `input` may or may not be modified.
204
410k
inline bool get_length_prefixed_slice(Slice* input, Slice* val) {
205
410k
    uint32_t len;
206
410k
    if (get_varint32(input, &len) && input->get_size() >= len) {
207
404k
        *val = Slice(input->get_data(), len);
208
404k
        input->remove_prefix(len);
209
404k
        return true;
210
404k
    } else {
211
6.06k
        return false;
212
6.06k
    }
213
410k
}
214
215
} // namespace doris