/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 |