Coverage Report

Created: 2024-11-21 23:45

/root/doris/be/src/util/coding.h
Line
Count
Source (jump to first uncovered line)
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
#ifndef __APPLE__
12
#include <endian.h>
13
#endif
14
#include <stdint.h>
15
#include <string.h>
16
17
#include "olap/olap_common.h"
18
#include "util/slice.h"
19
20
namespace doris {
21
22
// TODO(zc): add encode big endian later when we need it
23
// use big endian when we have order requirement.
24
// little endian is more efficient when we use X86 CPU, so
25
// when we have no order needs, we prefer little endian encoding
26
1
inline void encode_fixed8(uint8_t* buf, uint8_t val) {
27
1
    *buf = val;
28
1
}
29
30
985
inline void encode_fixed16_le(uint8_t* buf, uint16_t val) {
31
985
#if __BYTE_ORDER == __LITTLE_ENDIAN
32
985
    memcpy(buf, &val, sizeof(val));
33
#else
34
    uint16_t res = bswap_16(val);
35
    memcpy(buf, &res, sizeof(res));
36
#endif
37
985
}
38
39
158k
inline void encode_fixed32_le(uint8_t* buf, uint32_t val) {
40
158k
#if __BYTE_ORDER == __LITTLE_ENDIAN
41
158k
    memcpy(buf, &val, sizeof(val));
42
#else
43
    uint32_t res = bswap_32(val);
44
    memcpy(buf, &res, sizeof(res));
45
#endif
46
158k
}
47
48
6.43k
inline void encode_fixed64_le(uint8_t* buf, uint64_t val) {
49
6.43k
#if __BYTE_ORDER == __LITTLE_ENDIAN
50
6.43k
    memcpy(buf, &val, sizeof(val));
51
#else
52
    uint64_t res = gbswap_64(val);
53
    memcpy(buf, &res, sizeof(res));
54
#endif
55
6.43k
}
56
57
0
inline void encode_fixed128_le(uint8_t* buf, uint128_t val) {
58
0
#if __BYTE_ORDER == __LITTLE_ENDIAN
59
0
    memcpy(buf, &val, sizeof(val));
60
#else
61
    uint128_t res = gbswap_128(val);
62
    memcpy(buf, &res, sizeof(res));
63
#endif
64
0
}
65
66
535
inline uint8_t decode_fixed8(const uint8_t* buf) {
67
535
    return *buf;
68
535
}
69
70
40.9k
inline uint16_t decode_fixed16_le(const uint8_t* buf) {
71
40.9k
    uint16_t res;
72
40.9k
    memcpy(&res, buf, sizeof(res));
73
40.9k
#if __BYTE_ORDER == __LITTLE_ENDIAN
74
40.9k
    return res;
75
#else
76
    return bswap_16(res);
77
#endif
78
40.9k
}
79
80
180k
inline uint32_t decode_fixed32_le(const uint8_t* buf) {
81
180k
    uint32_t res;
82
180k
    memcpy(&res, buf, sizeof(res));
83
180k
#if __BYTE_ORDER == __LITTLE_ENDIAN
84
180k
    return res;
85
#else
86
    return bswap_32(res);
87
#endif
88
180k
}
89
90
15.5M
inline uint64_t decode_fixed64_le(const uint8_t* buf) {
91
15.5M
    uint64_t res;
92
15.5M
    memcpy(&res, buf, sizeof(res));
93
15.5M
#if __BYTE_ORDER == __LITTLE_ENDIAN
94
15.5M
    return res;
95
#else
96
    return gbswap_64(res);
97
#endif
98
15.5M
}
99
100
0
inline uint128_t decode_fixed128_le(const uint8_t* buf) {
101
0
    uint128_t res;
102
0
    memcpy(&res, buf, sizeof(res));
103
0
#if __BYTE_ORDER == __LITTLE_ENDIAN
104
0
    return res;
105
#else
106
    return gbswap_128(res);
107
#endif
108
0
}
109
110
template <typename T>
111
88.2k
void put_fixed32_le(T* dst, uint32_t val) {
112
88.2k
    uint8_t buf[sizeof(val)];
113
88.2k
    encode_fixed32_le(buf, val);
114
88.2k
    dst->append((char*)buf, sizeof(buf));
115
88.2k
}
_ZN5doris14put_fixed32_leINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEvPT_j
Line
Count
Source
111
26.1k
void put_fixed32_le(T* dst, uint32_t val) {
112
26.1k
    uint8_t buf[sizeof(val)];
113
26.1k
    encode_fixed32_le(buf, val);
114
26.1k
    dst->append((char*)buf, sizeof(buf));
115
26.1k
}
_ZN5doris14put_fixed32_leINS_10faststringEEEvPT_j
Line
Count
Source
111
62.0k
void put_fixed32_le(T* dst, uint32_t val) {
112
62.0k
    uint8_t buf[sizeof(val)];
113
62.0k
    encode_fixed32_le(buf, val);
114
62.0k
    dst->append((char*)buf, sizeof(buf));
115
62.0k
}
116
117
template <typename T>
118
640
void put_fixed64_le(T* dst, uint64_t val) {
119
640
    uint8_t buf[sizeof(val)];
120
640
    encode_fixed64_le(buf, val);
121
640
    dst->append((char*)buf, sizeof(buf));
122
640
}
_ZN5doris14put_fixed64_leINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEvPT_m
Line
Count
Source
118
615
void put_fixed64_le(T* dst, uint64_t val) {
119
615
    uint8_t buf[sizeof(val)];
120
615
    encode_fixed64_le(buf, val);
121
615
    dst->append((char*)buf, sizeof(buf));
122
615
}
_ZN5doris14put_fixed64_leINS_10faststringEEEvPT_m
Line
Count
Source
118
25
void put_fixed64_le(T* dst, uint64_t val) {
119
25
    uint8_t buf[sizeof(val)];
120
25
    encode_fixed64_le(buf, val);
121
25
    dst->append((char*)buf, sizeof(buf));
122
25
}
123
124
// Returns the length of the varint32 or varint64 encoding of "v"
125
13
inline int varint_length(uint64_t v) {
126
13
    int len = 1;
127
13
    while (v >= 128) {
128
0
        v >>= 7;
129
0
        len++;
130
0
    }
131
13
    return len;
132
13
}
133
134
template <typename T>
135
0
void put_fixed128_le(T* dst, uint128_t val) {
136
0
    uint8_t buf[sizeof(val)];
137
0
    encode_fixed128_le(buf, val);
138
0
    dst->append((char*)buf, sizeof(buf));
139
0
}
140
141
extern uint8_t* encode_varint32(uint8_t* dst, uint32_t value);
142
extern uint8_t* encode_varint64(uint8_t* dst, uint64_t value);
143
144
37.7k
inline uint8_t* encode_varint64(uint8_t* dst, uint64_t v) {
145
37.7k
    static const unsigned int B = 128;
146
103k
    while (v >= B) {
147
        // Fetch low seven bits from current v, and the eight bit is marked as compression mark.
148
        // v | B is optimised from (v & (B-1)) | B, because result is assigned to uint8_t and other bits
149
        // is cleared by implicit conversion.
150
65.6k
        *(dst++) = v | B;
151
65.6k
        v >>= 7;
152
65.6k
    }
153
37.7k
    *(dst++) = static_cast<unsigned char>(v);
154
37.7k
    return dst;
155
37.7k
}
156
157
extern const uint8_t* decode_varint32_ptr_fallback(const uint8_t* p, const uint8_t* limit,
158
                                                   uint32_t* value);
159
160
inline const uint8_t* decode_varint32_ptr(const uint8_t* ptr, const uint8_t* limit,
161
503k
                                          uint32_t* value) {
162
503k
    if (ptr < limit) {
163
503k
        uint32_t result = *ptr;
164
503k
        if ((result & 128) == 0) {
165
475k
            *value = result;
166
475k
            return ptr + 1;
167
475k
        }
168
503k
    }
169
27.2k
    return decode_varint32_ptr_fallback(ptr, limit, value);
170
503k
}
171
172
extern const uint8_t* decode_varint64_ptr(const uint8_t* p, const uint8_t* limit, uint64_t* value);
173
174
template <typename T>
175
321k
void put_varint32(T* dst, uint32_t v) {
176
321k
    uint8_t buf[16];
177
321k
    uint8_t* ptr = encode_varint32(buf, v);
178
321k
    dst->append((char*)buf, static_cast<size_t>(ptr - buf));
179
321k
}
_ZN5doris12put_varint32INSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEvPT_j
Line
Count
Source
175
1
void put_varint32(T* dst, uint32_t v) {
176
1
    uint8_t buf[16];
177
1
    uint8_t* ptr = encode_varint32(buf, v);
178
1
    dst->append((char*)buf, static_cast<size_t>(ptr - buf));
179
1
}
_ZN5doris12put_varint32INS_10faststringEEEvPT_j
Line
Count
Source
175
321k
void put_varint32(T* dst, uint32_t v) {
176
321k
    uint8_t buf[16];
177
321k
    uint8_t* ptr = encode_varint32(buf, v);
178
321k
    dst->append((char*)buf, static_cast<size_t>(ptr - buf));
179
321k
}
180
181
template <typename T>
182
1
void put_varint64(T* dst, uint64_t v) {
183
1
    uint8_t buf[16];
184
1
    uint8_t* ptr = encode_varint64(buf, v);
185
1
    dst->append((char*)buf, static_cast<size_t>(ptr - buf));
186
1
}
187
188
template <typename T>
189
37.7k
void put_length_prefixed_slice(T* dst, const Slice& value) {
190
37.7k
    put_varint32(dst, value.get_size());
191
37.7k
    dst->append(value.get_data(), value.get_size());
192
37.7k
}
193
194
template <typename T>
195
37.7k
void put_varint64_varint32(T* dst, uint64_t v1, uint32_t v2) {
196
37.7k
    uint8_t buf[16];
197
37.7k
    uint8_t* ptr = encode_varint64(buf, v1);
198
37.7k
    ptr = encode_varint32(ptr, v2);
199
37.7k
    dst->append((char*)buf, static_cast<size_t>(ptr - buf));
200
37.7k
}
_ZN5doris21put_varint64_varint32INS_10faststringEEEvPT_mj
Line
Count
Source
195
37.7k
void put_varint64_varint32(T* dst, uint64_t v1, uint32_t v2) {
196
37.7k
    uint8_t buf[16];
197
37.7k
    uint8_t* ptr = encode_varint64(buf, v1);
198
37.7k
    ptr = encode_varint32(ptr, v2);
199
37.7k
    dst->append((char*)buf, static_cast<size_t>(ptr - buf));
200
37.7k
}
_ZN5doris21put_varint64_varint32INSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEvPT_mj
Line
Count
Source
195
1
void put_varint64_varint32(T* dst, uint64_t v1, uint32_t v2) {
196
1
    uint8_t buf[16];
197
1
    uint8_t* ptr = encode_varint64(buf, v1);
198
1
    ptr = encode_varint32(ptr, v2);
199
1
    dst->append((char*)buf, static_cast<size_t>(ptr - buf));
200
1
}
201
202
// parse a varint32 from the start of `input` into `val`.
203
// on success, return true and advance `input` past the parsed value.
204
// on failure, return false and `input` is not modified.
205
55.5k
inline bool get_varint32(Slice* input, uint32_t* val) {
206
55.5k
    const uint8_t* p = (const uint8_t*)input->data;
207
55.5k
    const uint8_t* limit = p + input->size;
208
55.5k
    const uint8_t* q = decode_varint32_ptr(p, limit, val);
209
55.5k
    if (q == nullptr) {
210
0
        return false;
211
55.5k
    } else {
212
55.5k
        *input = Slice(q, limit - q);
213
55.5k
        return true;
214
55.5k
    }
215
55.5k
}
216
217
// parse a varint64 from the start of `input` into `val`.
218
// on success, return true and advance `input` past the parsed value.
219
// on failure, return false and `input` is not modified.
220
17.2k
inline bool get_varint64(Slice* input, uint64_t* val) {
221
17.2k
    const uint8_t* p = (const uint8_t*)input->data;
222
17.2k
    const uint8_t* limit = p + input->size;
223
17.2k
    const uint8_t* q = decode_varint64_ptr(p, limit, val);
224
17.2k
    if (q == nullptr) {
225
0
        return false;
226
17.2k
    } else {
227
17.2k
        *input = Slice(q, limit - q);
228
17.2k
        return true;
229
17.2k
    }
230
17.2k
}
231
232
// parse a length-prefixed-slice from the start of `input` into `val`.
233
// on success, return true and advance `input` past the parsed value.
234
// on failure, return false and `input` may or may not be modified.
235
17.2k
inline bool get_length_prefixed_slice(Slice* input, Slice* val) {
236
17.2k
    uint32_t len;
237
17.2k
    if (get_varint32(input, &len) && input->get_size() >= len) {
238
17.2k
        *val = Slice(input->get_data(), len);
239
17.2k
        input->remove_prefix(len);
240
17.2k
        return true;
241
17.2k
    } else {
242
0
        return false;
243
0
    }
244
17.2k
}
245
246
} // namespace doris