/src/rocksdb/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 | | // |
6 | | // Copyright (c) 2011 The LevelDB Authors. All rights reserved. |
7 | | // Use of this source code is governed by a BSD-style license that can be |
8 | | // found in the LICENSE file. See the AUTHORS file for names of contributors. |
9 | | // |
10 | | // Encoding independent of machine byte order: |
11 | | // * Fixed-length numbers are encoded with least-significant byte first |
12 | | // (little endian, native order on Intel and others) |
13 | | // * In addition we support variable length "varint" encoding |
14 | | // * Strings are encoded prefixed by their length in varint format |
15 | | // |
16 | | // Some related functions are provided in coding_lean.h |
17 | | |
18 | | #pragma once |
19 | | #include <algorithm> |
20 | | #include <string> |
21 | | #include <type_traits> |
22 | | |
23 | | #include "port/port.h" |
24 | | #include "rocksdb/slice.h" |
25 | | #include "util/cast_util.h" |
26 | | #include "util/coding_lean.h" |
27 | | |
28 | | // Some processors does not allow unaligned access to memory |
29 | | #if defined(__sparc) |
30 | | #define PLATFORM_UNALIGNED_ACCESS_NOT_ALLOWED |
31 | | #endif |
32 | | |
33 | | namespace ROCKSDB_NAMESPACE { |
34 | | |
35 | | // The maximum length of a varint in bytes for 64-bit. |
36 | | const uint32_t kMaxVarint64Length = 10; |
37 | | |
38 | | // Standard Put... routines append to a string |
39 | | void PutFixed16(std::string* dst, uint16_t value); |
40 | | void PutFixed32(std::string* dst, uint32_t value); |
41 | | void PutFixed64(std::string* dst, uint64_t value); |
42 | | |
43 | | template <typename... Args> |
44 | | void PutVarint32(std::string* dst, Args... args); |
45 | | void PutVarint64(std::string* dst, uint64_t value); |
46 | | void PutVarint64Varint64(std::string* dst, uint64_t value1, uint64_t value2); |
47 | | void PutVarint32Varint64(std::string* dst, uint32_t value1, uint64_t value2); |
48 | | void PutVarint32Varint32Varint64(std::string* dst, uint32_t value1, |
49 | | uint32_t value2, uint64_t value3); |
50 | | void PutLengthPrefixedSlice(std::string* dst, const Slice& value); |
51 | | void PutLengthPrefixedSliceParts(std::string* dst, |
52 | | const SliceParts& slice_parts); |
53 | | void PutLengthPrefixedSlicePartsWithPadding(std::string* dst, |
54 | | const SliceParts& slice_parts, |
55 | | size_t pad_sz); |
56 | | |
57 | | // Standard Get... routines parse a value from the beginning of a Slice |
58 | | // and advance the slice past the parsed value. |
59 | | bool GetFixed64(Slice* input, uint64_t* value); |
60 | | bool GetFixed32(Slice* input, uint32_t* value); |
61 | | bool GetFixed16(Slice* input, uint16_t* value); |
62 | | bool GetVarint32(Slice* input, uint32_t* value); |
63 | | bool GetVarint64(Slice* input, uint64_t* value); |
64 | | bool GetVarsignedint64(Slice* input, int64_t* value); |
65 | | bool GetLengthPrefixedSlice(Slice* input, Slice* result); |
66 | | // This function assumes data is well-formed. |
67 | | Slice GetLengthPrefixedSlice(const char* data); |
68 | | |
69 | | Slice GetSliceUntil(Slice* slice, char delimiter); |
70 | | |
71 | | // Borrowed from |
72 | | // https://github.com/facebook/fbthrift/blob/449a5f77f9f9bae72c9eb5e78093247eef185c04/thrift/lib/cpp/util/VarintUtils-inl.h#L202-L208 |
73 | 3.08k | constexpr inline uint64_t i64ToZigzag(const int64_t l) { |
74 | 3.08k | return (static_cast<uint64_t>(l) << 1) ^ static_cast<uint64_t>(l >> 63); |
75 | 3.08k | } |
76 | 0 | inline int64_t zigzagToI64(uint64_t n) { |
77 | 0 | return (n >> 1) ^ -static_cast<int64_t>(n & 1); |
78 | 0 | } |
79 | | |
80 | | // Pointer-based variants of GetVarint... These either store a value |
81 | | // in *v and return a pointer just past the parsed value, or return |
82 | | // nullptr on error. These routines only look at bytes in the range |
83 | | // [p..limit-1] |
84 | | const char* GetVarint32Ptr(const char* p, const char* limit, uint32_t* v); |
85 | | const char* GetVarint64Ptr(const char* p, const char* limit, uint64_t* v); |
86 | | inline const char* GetVarsignedint64Ptr(const char* p, const char* limit, |
87 | 0 | int64_t* value) { |
88 | 0 | uint64_t u = 0; |
89 | 0 | const char* ret = GetVarint64Ptr(p, limit, &u); |
90 | 0 | *value = zigzagToI64(u); |
91 | 0 | return ret; |
92 | 0 | } |
93 | | |
94 | | // Returns the length of the varint32 or varint64 encoding of "v" |
95 | | uint16_t VarintLength(uint64_t v); |
96 | | |
97 | | // Lower-level versions of Put... that write directly into a character buffer |
98 | | // and return a pointer just past the last byte written. |
99 | | // REQUIRES: dst has enough space for the value being written |
100 | | char* EncodeVarint32(char* dst, uint32_t value); |
101 | | char* EncodeVarint64(char* dst, uint64_t value); |
102 | | |
103 | | // Internal routine for use by fallback path of GetVarint32Ptr |
104 | | const char* GetVarint32PtrFallback(const char* p, const char* limit, |
105 | | uint32_t* value); |
106 | | inline const char* GetVarint32Ptr(const char* p, const char* limit, |
107 | 19.2M | uint32_t* value) { |
108 | 19.2M | if (p < limit) { |
109 | 18.8M | uint32_t result = *(lossless_cast<const unsigned char*>(p)); |
110 | 18.8M | if ((result & 128) == 0) { |
111 | 16.5M | *value = result; |
112 | 16.5M | return p + 1; |
113 | 16.5M | } |
114 | 18.8M | } |
115 | 2.67M | return GetVarint32PtrFallback(p, limit, value); |
116 | 19.2M | } |
117 | | |
118 | | // Pull the last 8 bits and cast it to a character |
119 | 0 | inline void PutFixed16(std::string* dst, uint16_t value) { |
120 | 0 | if (port::kLittleEndian) { |
121 | 0 | dst->append(const_cast<const char*>(reinterpret_cast<char*>(&value)), |
122 | 0 | sizeof(value)); |
123 | 0 | } else { |
124 | 0 | char buf[sizeof(value)]; |
125 | 0 | EncodeFixed16(buf, value); |
126 | 0 | dst->append(buf, sizeof(buf)); |
127 | 0 | } |
128 | 0 | } |
129 | | |
130 | 295k | inline void PutFixed32(std::string* dst, uint32_t value) { |
131 | 295k | if (port::kLittleEndian) { |
132 | 295k | dst->append(const_cast<const char*>(reinterpret_cast<char*>(&value)), |
133 | 295k | sizeof(value)); |
134 | 295k | } else { |
135 | 0 | char buf[sizeof(value)]; |
136 | 0 | EncodeFixed32(buf, value); |
137 | 0 | dst->append(buf, sizeof(buf)); |
138 | 0 | } |
139 | 295k | } |
140 | | |
141 | 53.7M | inline void PutFixed64(std::string* dst, uint64_t value) { |
142 | 53.7M | if (port::kLittleEndian) { |
143 | 53.7M | dst->append(const_cast<const char*>(reinterpret_cast<char*>(&value)), |
144 | 53.7M | sizeof(value)); |
145 | 53.7M | } else { |
146 | 0 | char buf[sizeof(value)]; |
147 | 0 | EncodeFixed64(buf, value); |
148 | 0 | dst->append(buf, sizeof(buf)); |
149 | 0 | } |
150 | 53.7M | } |
151 | | |
152 | | template <typename... Args> |
153 | 4.61M | inline void PutVarint32(std::string* dst, Args... args) { |
154 | 4.61M | static_assert((std::is_convertible_v<Args, uint32_t> && ...), |
155 | 4.61M | "All arguments must be convertible to uint32_t"); |
156 | 4.61M | constexpr size_t kMaxBytesPerVarint32 = 5; |
157 | 4.61M | char buf[sizeof...(args) * kMaxBytesPerVarint32]; |
158 | 4.61M | char* ptr = buf; |
159 | 4.61M | ((ptr = EncodeVarint32(ptr, static_cast<uint32_t>(args))), ...); |
160 | 4.61M | dst->append(buf, static_cast<size_t>(ptr - buf)); |
161 | 4.61M | } void rocksdb::PutVarint32<unsigned int>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >*, unsigned int) Line | Count | Source | 153 | 2.18M | inline void PutVarint32(std::string* dst, Args... args) { | 154 | 2.18M | static_assert((std::is_convertible_v<Args, uint32_t> && ...), | 155 | 2.18M | "All arguments must be convertible to uint32_t"); | 156 | 2.18M | constexpr size_t kMaxBytesPerVarint32 = 5; | 157 | 2.18M | char buf[sizeof...(args) * kMaxBytesPerVarint32]; | 158 | 2.18M | char* ptr = buf; | 159 | 2.18M | ((ptr = EncodeVarint32(ptr, static_cast<uint32_t>(args))), ...); | 160 | 2.18M | dst->append(buf, static_cast<size_t>(ptr - buf)); | 161 | 2.18M | } |
void rocksdb::PutVarint32<rocksdb::Tag>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >*, rocksdb::Tag) Line | Count | Source | 153 | 487k | inline void PutVarint32(std::string* dst, Args... args) { | 154 | 487k | static_assert((std::is_convertible_v<Args, uint32_t> && ...), | 155 | 487k | "All arguments must be convertible to uint32_t"); | 156 | 487k | constexpr size_t kMaxBytesPerVarint32 = 5; | 157 | 487k | char buf[sizeof...(args) * kMaxBytesPerVarint32]; | 158 | 487k | char* ptr = buf; | 159 | 487k | ((ptr = EncodeVarint32(ptr, static_cast<uint32_t>(args))), ...); | 160 | 487k | dst->append(buf, static_cast<size_t>(ptr - buf)); | 161 | 487k | } |
void rocksdb::PutVarint32<rocksdb::Tag, unsigned int>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >*, rocksdb::Tag, unsigned int) Line | Count | Source | 153 | 138k | inline void PutVarint32(std::string* dst, Args... args) { | 154 | 138k | static_assert((std::is_convertible_v<Args, uint32_t> && ...), | 155 | 138k | "All arguments must be convertible to uint32_t"); | 156 | 138k | constexpr size_t kMaxBytesPerVarint32 = 5; | 157 | 138k | char buf[sizeof...(args) * kMaxBytesPerVarint32]; | 158 | 138k | char* ptr = buf; | 159 | 138k | ((ptr = EncodeVarint32(ptr, static_cast<uint32_t>(args))), ...); | 160 | 138k | dst->append(buf, static_cast<size_t>(ptr - buf)); | 161 | 138k | } |
Unexecuted instantiation: void rocksdb::PutVarint32<int>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >*, int) void rocksdb::PutVarint32<rocksdb::NewFileCustomTag>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >*, rocksdb::NewFileCustomTag) Line | Count | Source | 153 | 729k | inline void PutVarint32(std::string* dst, Args... args) { | 154 | 729k | static_assert((std::is_convertible_v<Args, uint32_t> && ...), | 155 | 729k | "All arguments must be convertible to uint32_t"); | 156 | 729k | constexpr size_t kMaxBytesPerVarint32 = 5; | 157 | 729k | char buf[sizeof...(args) * kMaxBytesPerVarint32]; | 158 | 729k | char* ptr = buf; | 159 | 729k | ((ptr = EncodeVarint32(ptr, static_cast<uint32_t>(args))), ...); | 160 | 729k | dst->append(buf, static_cast<size_t>(ptr - buf)); | 161 | 729k | } |
Unexecuted instantiation: void rocksdb::PutVarint32<rocksdb::SubcompactionProgressPerLevelCustomTag>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >*, rocksdb::SubcompactionProgressPerLevelCustomTag) Unexecuted instantiation: void rocksdb::PutVarint32<rocksdb::SubcompactionProgressCustomTag>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >*, rocksdb::SubcompactionProgressCustomTag) Unexecuted instantiation: void rocksdb::PutVarint32<rocksdb::BlobFileAddition::CustomFieldTags>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >*, rocksdb::BlobFileAddition::CustomFieldTags) Unexecuted instantiation: void rocksdb::PutVarint32<rocksdb::BlobFileGarbage::CustomFieldTags>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >*, rocksdb::BlobFileGarbage::CustomFieldTags) void rocksdb::PutVarint32<unsigned int, unsigned int, unsigned int>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >*, unsigned int, unsigned int, unsigned int) Line | Count | Source | 153 | 1.02M | inline void PutVarint32(std::string* dst, Args... args) { | 154 | 1.02M | static_assert((std::is_convertible_v<Args, uint32_t> && ...), | 155 | 1.02M | "All arguments must be convertible to uint32_t"); | 156 | 1.02M | constexpr size_t kMaxBytesPerVarint32 = 5; | 157 | 1.02M | char buf[sizeof...(args) * kMaxBytesPerVarint32]; | 158 | 1.02M | char* ptr = buf; | 159 | 1.02M | ((ptr = EncodeVarint32(ptr, static_cast<uint32_t>(args))), ...); | 160 | 1.02M | dst->append(buf, static_cast<size_t>(ptr - buf)); | 161 | 1.02M | } |
void rocksdb::PutVarint32<unsigned int, unsigned int>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >*, unsigned int, unsigned int) Line | Count | Source | 153 | 46.9k | inline void PutVarint32(std::string* dst, Args... args) { | 154 | 46.9k | static_assert((std::is_convertible_v<Args, uint32_t> && ...), | 155 | 46.9k | "All arguments must be convertible to uint32_t"); | 156 | 46.9k | constexpr size_t kMaxBytesPerVarint32 = 5; | 157 | 46.9k | char buf[sizeof...(args) * kMaxBytesPerVarint32]; | 158 | 46.9k | char* ptr = buf; | 159 | 46.9k | ((ptr = EncodeVarint32(ptr, static_cast<uint32_t>(args))), ...); | 160 | 46.9k | dst->append(buf, static_cast<size_t>(ptr - buf)); | 161 | 46.9k | } |
Unexecuted instantiation: void rocksdb::PutVarint32<unsigned int, unsigned int, unsigned int, unsigned int>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >*, unsigned int, unsigned int, unsigned int, unsigned int) |
162 | | |
163 | 2.75M | inline char* EncodeVarint64(char* dst, uint64_t v) { |
164 | 2.75M | static const unsigned int B = 128; |
165 | 2.75M | unsigned char* ptr = lossless_cast<unsigned char*>(dst); |
166 | 3.91M | while (v >= B) { |
167 | 1.15M | *(ptr++) = (v & (B - 1)) | B; |
168 | 1.15M | v >>= 7; |
169 | 1.15M | } |
170 | 2.75M | *(ptr++) = static_cast<unsigned char>(v); |
171 | 2.75M | return lossless_cast<char*>(ptr); |
172 | 2.75M | } |
173 | | |
174 | 1.24M | inline void PutVarint64(std::string* dst, uint64_t v) { |
175 | 1.24M | char buf[kMaxVarint64Length]; |
176 | 1.24M | char* ptr = EncodeVarint64(buf, v); |
177 | 1.24M | dst->append(buf, static_cast<size_t>(ptr - buf)); |
178 | 1.24M | } |
179 | | |
180 | 3.08k | inline void PutVarsignedint64(std::string* dst, int64_t v) { |
181 | 3.08k | char buf[kMaxVarint64Length]; |
182 | | // Using Zigzag format to convert signed to unsigned |
183 | 3.08k | char* ptr = EncodeVarint64(buf, i64ToZigzag(v)); |
184 | 3.08k | dst->append(buf, static_cast<size_t>(ptr - buf)); |
185 | 3.08k | } |
186 | | |
187 | 184k | inline void PutVarint64Varint64(std::string* dst, uint64_t v1, uint64_t v2) { |
188 | 184k | char buf[20]; |
189 | 184k | char* ptr = EncodeVarint64(buf, v1); |
190 | 184k | ptr = EncodeVarint64(ptr, v2); |
191 | 184k | dst->append(buf, static_cast<size_t>(ptr - buf)); |
192 | 184k | } |
193 | | |
194 | 1.12M | inline void PutVarint32Varint64(std::string* dst, uint32_t v1, uint64_t v2) { |
195 | 1.12M | char buf[15]; |
196 | 1.12M | char* ptr = EncodeVarint32(buf, v1); |
197 | 1.12M | ptr = EncodeVarint64(ptr, v2); |
198 | 1.12M | dst->append(buf, static_cast<size_t>(ptr - buf)); |
199 | 1.12M | } |
200 | | |
201 | | inline void PutVarint32Varint32Varint64(std::string* dst, uint32_t v1, |
202 | 15.1k | uint32_t v2, uint64_t v3) { |
203 | 15.1k | char buf[20]; |
204 | 15.1k | char* ptr = EncodeVarint32(buf, v1); |
205 | 15.1k | ptr = EncodeVarint32(ptr, v2); |
206 | 15.1k | ptr = EncodeVarint64(ptr, v3); |
207 | 15.1k | dst->append(buf, static_cast<size_t>(ptr - buf)); |
208 | 15.1k | } |
209 | | |
210 | 2.15M | inline void PutLengthPrefixedSlice(std::string* dst, const Slice& value) { |
211 | 2.15M | PutVarint32(dst, static_cast<uint32_t>(value.size())); |
212 | 2.15M | dst->append(value.data(), value.size()); |
213 | 2.15M | } |
214 | | |
215 | | inline void PutLengthPrefixedSliceParts(std::string* dst, size_t total_bytes, |
216 | 0 | const SliceParts& slice_parts) { |
217 | 0 | for (int i = 0; i < slice_parts.num_parts; ++i) { |
218 | 0 | total_bytes += slice_parts.parts[i].size(); |
219 | 0 | } |
220 | 0 | PutVarint32(dst, static_cast<uint32_t>(total_bytes)); |
221 | 0 | for (int i = 0; i < slice_parts.num_parts; ++i) { |
222 | 0 | dst->append(slice_parts.parts[i].data(), slice_parts.parts[i].size()); |
223 | 0 | } |
224 | 0 | } |
225 | | |
226 | | inline void PutLengthPrefixedSliceParts(std::string* dst, |
227 | 0 | const SliceParts& slice_parts) { |
228 | 0 | PutLengthPrefixedSliceParts(dst, /*total_bytes=*/0, slice_parts); |
229 | 0 | } |
230 | | |
231 | | inline void PutLengthPrefixedSlicePartsWithPadding( |
232 | 0 | std::string* dst, const SliceParts& slice_parts, size_t pad_sz) { |
233 | 0 | PutLengthPrefixedSliceParts(dst, /*total_bytes=*/pad_sz, slice_parts); |
234 | 0 | dst->append(pad_sz, '\0'); |
235 | 0 | } |
236 | | |
237 | 1.90M | inline uint16_t VarintLength(uint64_t v) { |
238 | 1.90M | uint16_t len = 1; |
239 | 2.10M | while (v >= 128) { |
240 | 203k | v >>= 7; |
241 | 203k | len++; |
242 | 203k | } |
243 | 1.90M | return len; |
244 | 1.90M | } |
245 | | |
246 | 132k | inline bool GetFixed64(Slice* input, uint64_t* value) { |
247 | 132k | if (input->size() < sizeof(uint64_t)) { |
248 | 0 | return false; |
249 | 0 | } |
250 | 132k | *value = DecodeFixed64(input->data()); |
251 | 132k | input->remove_prefix(sizeof(uint64_t)); |
252 | 132k | return true; |
253 | 132k | } |
254 | | |
255 | 314k | inline bool GetFixed32(Slice* input, uint32_t* value) { |
256 | 314k | if (input->size() < sizeof(uint32_t)) { |
257 | 0 | return false; |
258 | 0 | } |
259 | 314k | *value = DecodeFixed32(input->data()); |
260 | 314k | input->remove_prefix(sizeof(uint32_t)); |
261 | 314k | return true; |
262 | 314k | } |
263 | | |
264 | 0 | inline bool GetFixed16(Slice* input, uint16_t* value) { |
265 | 0 | if (input->size() < sizeof(uint16_t)) { |
266 | 0 | return false; |
267 | 0 | } |
268 | 0 | *value = DecodeFixed16(input->data()); |
269 | 0 | input->remove_prefix(sizeof(uint16_t)); |
270 | 0 | return true; |
271 | 0 | } |
272 | | |
273 | 7.60M | inline bool GetVarint32(Slice* input, uint32_t* value) { |
274 | 7.60M | const char* p = input->data(); |
275 | 7.60M | const char* limit = p + input->size(); |
276 | 7.60M | const char* q = GetVarint32Ptr(p, limit, value); |
277 | 7.60M | if (q == nullptr) { |
278 | 458k | return false; |
279 | 7.14M | } else { |
280 | 7.14M | *input = Slice(q, static_cast<size_t>(limit - q)); |
281 | 7.14M | return true; |
282 | 7.14M | } |
283 | 7.60M | } |
284 | | |
285 | 5.22M | inline bool GetVarint64(Slice* input, uint64_t* value) { |
286 | 5.22M | const char* p = input->data(); |
287 | 5.22M | const char* limit = p + input->size(); |
288 | 5.22M | const char* q = GetVarint64Ptr(p, limit, value); |
289 | 5.22M | if (q == nullptr) { |
290 | 0 | return false; |
291 | 5.22M | } else { |
292 | 5.22M | *input = Slice(q, static_cast<size_t>(limit - q)); |
293 | 5.22M | return true; |
294 | 5.22M | } |
295 | 5.22M | } |
296 | | |
297 | 0 | inline bool GetVarsignedint64(Slice* input, int64_t* value) { |
298 | 0 | const char* p = input->data(); |
299 | 0 | const char* limit = p + input->size(); |
300 | 0 | const char* q = GetVarsignedint64Ptr(p, limit, value); |
301 | 0 | if (q == nullptr) { |
302 | 0 | return false; |
303 | 0 | } else { |
304 | 0 | *input = Slice(q, static_cast<size_t>(limit - q)); |
305 | 0 | return true; |
306 | 0 | } |
307 | 0 | } |
308 | | |
309 | 3.88M | inline bool GetLengthPrefixedSlice(Slice* input, Slice* result) { |
310 | 3.88M | uint32_t len = 0; |
311 | 3.88M | if (GetVarint32(input, &len) && input->size() >= len) { |
312 | 3.88M | *result = Slice(input->data(), len); |
313 | 3.88M | input->remove_prefix(len); |
314 | 3.88M | return true; |
315 | 3.88M | } else { |
316 | 0 | return false; |
317 | 0 | } |
318 | 3.88M | } |
319 | | |
320 | 11.1M | inline Slice GetLengthPrefixedSlice(const char* data) { |
321 | 11.1M | uint32_t len = 0; |
322 | | // +5: we assume "data" is not corrupted |
323 | | // unsigned char is 7 bits, uint32_t is 32 bits, need 5 unsigned char |
324 | 11.1M | auto p = GetVarint32Ptr(data, data + 5 /* limit */, &len); |
325 | 11.1M | return Slice(p, len); |
326 | 11.1M | } |
327 | | |
328 | 0 | inline Slice GetSliceUntil(Slice* slice, char delimiter) { |
329 | 0 | uint32_t len = 0; |
330 | 0 | for (len = 0; len < slice->size() && slice->data()[len] != delimiter; ++len) { |
331 | 0 | // nothing |
332 | 0 | } |
333 | 0 |
|
334 | 0 | Slice ret(slice->data(), len); |
335 | 0 | slice->remove_prefix(len + ((len < slice->size()) ? 1 : 0)); |
336 | 0 | return ret; |
337 | 0 | } |
338 | | |
339 | | template <class T> |
340 | | #ifdef ROCKSDB_UBSAN_RUN |
341 | | #if defined(__clang__) |
342 | | __attribute__((__no_sanitize__("alignment"))) |
343 | | #elif defined(__GNUC__) |
344 | | __attribute__((__no_sanitize_undefined__)) |
345 | | #endif |
346 | | #endif |
347 | 6.45M | inline void PutUnaligned(T* memory, const T& value) { |
348 | | #if defined(PLATFORM_UNALIGNED_ACCESS_NOT_ALLOWED) |
349 | | char* nonAlignedMemory = reinterpret_cast<char*>(memory); |
350 | | memcpy(nonAlignedMemory, reinterpret_cast<const char*>(&value), sizeof(T)); |
351 | | #else |
352 | 6.45M | *memory = value; |
353 | 6.45M | #endif |
354 | 6.45M | } void rocksdb::PutUnaligned<long>(long*, long const&) Line | Count | Source | 347 | 123k | inline void PutUnaligned(T* memory, const T& value) { | 348 | | #if defined(PLATFORM_UNALIGNED_ACCESS_NOT_ALLOWED) | 349 | | char* nonAlignedMemory = reinterpret_cast<char*>(memory); | 350 | | memcpy(nonAlignedMemory, reinterpret_cast<const char*>(&value), sizeof(T)); | 351 | | #else | 352 | 123k | *memory = value; | 353 | 123k | #endif | 354 | 123k | } |
void rocksdb::PutUnaligned<unsigned long>(unsigned long*, unsigned long const&) Line | Count | Source | 347 | 6.33M | inline void PutUnaligned(T* memory, const T& value) { | 348 | | #if defined(PLATFORM_UNALIGNED_ACCESS_NOT_ALLOWED) | 349 | | char* nonAlignedMemory = reinterpret_cast<char*>(memory); | 350 | | memcpy(nonAlignedMemory, reinterpret_cast<const char*>(&value), sizeof(T)); | 351 | | #else | 352 | 6.33M | *memory = value; | 353 | 6.33M | #endif | 354 | 6.33M | } |
Unexecuted instantiation: void rocksdb::PutUnaligned<unsigned int>(unsigned int*, unsigned int const&) |
355 | | |
356 | | template <class T> |
357 | | #ifdef ROCKSDB_UBSAN_RUN |
358 | | #if defined(__clang__) |
359 | | __attribute__((__no_sanitize__("alignment"))) |
360 | | #elif defined(__GNUC__) |
361 | | __attribute__((__no_sanitize_undefined__)) |
362 | | #endif |
363 | | #endif |
364 | 26.2M | inline void GetUnaligned(const T* memory, T* value) { |
365 | | #if defined(PLATFORM_UNALIGNED_ACCESS_NOT_ALLOWED) |
366 | | char* nonAlignedMemory = reinterpret_cast<char*>(value); |
367 | | memcpy(nonAlignedMemory, reinterpret_cast<const char*>(memory), sizeof(T)); |
368 | | #else |
369 | 26.2M | *value = *memory; |
370 | 26.2M | #endif |
371 | 26.2M | } void rocksdb::GetUnaligned<long>(long const*, long*) Line | Count | Source | 364 | 494k | inline void GetUnaligned(const T* memory, T* value) { | 365 | | #if defined(PLATFORM_UNALIGNED_ACCESS_NOT_ALLOWED) | 366 | | char* nonAlignedMemory = reinterpret_cast<char*>(value); | 367 | | memcpy(nonAlignedMemory, reinterpret_cast<const char*>(memory), sizeof(T)); | 368 | | #else | 369 | 494k | *value = *memory; | 370 | 494k | #endif | 371 | 494k | } |
void rocksdb::GetUnaligned<unsigned long>(unsigned long const*, unsigned long*) Line | Count | Source | 364 | 25.7M | inline void GetUnaligned(const T* memory, T* value) { | 365 | | #if defined(PLATFORM_UNALIGNED_ACCESS_NOT_ALLOWED) | 366 | | char* nonAlignedMemory = reinterpret_cast<char*>(value); | 367 | | memcpy(nonAlignedMemory, reinterpret_cast<const char*>(memory), sizeof(T)); | 368 | | #else | 369 | 25.7M | *value = *memory; | 370 | 25.7M | #endif | 371 | 25.7M | } |
Unexecuted instantiation: void rocksdb::GetUnaligned<unsigned int>(unsigned int const*, unsigned int*) |
372 | | |
373 | | } // namespace ROCKSDB_NAMESPACE |