YugabyteDB (2.13.0.0-b42, bfc6a6643e7399ac8a0e81d06a3ee6d6571b33ab)

Coverage Report

Created: 2022-03-09 17:30

/Users/deen/code/yugabyte-db/src/yb/util/slice.h
Line
Count
Source (jump to first uncovered line)
1
// Copyright (c) 2011 The LevelDB Authors. All rights reserved.
2
// Use of this source code is governed by a BSD-style license that can be
3
// found in the LICENSE file. See the AUTHORS file for names of contributors.
4
//
5
// The following only applies to changes made to this file as part of YugaByte development.
6
//
7
// Portions Copyright (c) YugaByte, Inc.
8
//
9
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
10
// in compliance with the License.  You may obtain a copy of the License at
11
//
12
// http://www.apache.org/licenses/LICENSE-2.0
13
//
14
// Unless required by applicable law or agreed to in writing, software distributed under the License
15
// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
16
// or implied.  See the License for the specific language governing permissions and limitations
17
// under the License.
18
//
19
// Slice is a simple structure containing a pointer into some external
20
// storage and a size.  The user of a Slice must ensure that the slice
21
// is not used after the corresponding external storage has been
22
// deallocated.
23
//
24
// Multiple threads can invoke const methods on a Slice without
25
// external synchronization, but if any of the threads may call a
26
// non-const method, all threads accessing the same Slice must use
27
// external synchronization.
28
//
29
// Slices can be built around faststrings and GStringPieces using constructors
30
// with implicit casts. Both GStringPieces and faststrings depend on a great
31
// deal of gutil code, so these constructors are conditionalized on
32
// YB_HEADERS_USE_RICH_SLICE. Likewise, YB_HEADERS_USE_RICH_SLICE controls
33
// whether to use gutil-based memeq/memcmp substitutes; if it is unset, Slice
34
// will fall back to standard memcmp.
35
36
#ifndef YB_UTIL_SLICE_H_
37
#define YB_UTIL_SLICE_H_
38
39
#include <string>
40
41
#include "yb/gutil/strings/fastmem.h"
42
#include "yb/gutil/strings/stringpiece.h"
43
44
#include "yb/util/cast.h"
45
#include "yb/util/faststring.h"
46
#include "yb/util/status_fwd.h"
47
48
namespace yb {
49
50
struct SliceParts;
51
52
class Slice {
53
 public:
54
  // Create an empty slice.
55
2.44G
  Slice() : begin_(to_uchar_ptr("")), end_(begin_) { }
56
57
  // Create a slice that refers to d[0,n-1].
58
60.2G
  Slice(const uint8_t* d, size_t n) : begin_(d), end_(d + n) {}
59
  // Create a slice that refers to d[0,n-1].
60
31.7G
  Slice(const char* d, size_t n) : Slice(to_uchar_ptr(d), n) {}
Unexecuted instantiation: _ZN2yb5SliceC2EPKcm
_ZN2yb5SliceC1EPKcm
Line
Count
Source
60
31.7G
  Slice(const char* d, size_t n) : Slice(to_uchar_ptr(d), n) {}
61
62
  // Create a slice that refers to [begin, end).
63
999M
  Slice(const uint8_t* begin, const uint8_t* end) : begin_(begin), end_(end) {}
64
65
  template<size_t N>
66
185
  explicit Slice(const std::array<char, N>& arr) : Slice(arr.data(), N) {}
Unexecuted instantiation: _ZN2yb5SliceC1ILm18EEERKNSt3__15arrayIcXT_EEE
_ZN2yb5SliceC1ILm1EEERKNSt3__15arrayIcXT_EEE
Line
Count
Source
66
185
  explicit Slice(const std::array<char, N>& arr) : Slice(arr.data(), N) {}
67
68
  template<size_t N>
69
0
  explicit Slice(const std::array<unsigned char, N>& arr) : Slice(arr.data(), N) {}
70
71
  Slice(const char* begin, const char* end)
72
900M
      : Slice(to_uchar_ptr(begin), to_uchar_ptr(end)) {}
_ZN2yb5SliceC1EPKcS2_
Line
Count
Source
72
900M
      : Slice(to_uchar_ptr(begin), to_uchar_ptr(end)) {}
Unexecuted instantiation: _ZN2yb5SliceC2EPKcS2_
73
74
  // Create a slice that refers to the contents of "s"
75
  template <class CharTraits, class Allocator>
76
  Slice(const std::basic_string<char, CharTraits, Allocator>& s) // NOLINT(runtime/explicit)
77
1.82G
      : Slice(to_uchar_ptr(s.data()), s.size()) {}
_ZN2yb5SliceC1INSt3__111char_traitsIcEENS2_9allocatorIcEEEERKNS2_12basic_stringIcT_T0_EE
Line
Count
Source
77
1.82G
      : Slice(to_uchar_ptr(s.data()), s.size()) {}
_ZN2yb5SliceC1INSt3__111char_traitsIcEENS_8internal18ArenaAllocatorBaseIcNS5_11ArenaTraitsEEEEERKNS2_12basic_stringIcT_T0_EE
Line
Count
Source
77
3.89M
      : Slice(to_uchar_ptr(s.data()), s.size()) {}
78
79
  // Create a slice that refers to s[0,strlen(s)-1]
80
  Slice(const char* s) // NOLINT(runtime/explicit)
81
4.19G
      : Slice(to_uchar_ptr(s), strlen(s)) {}
Unexecuted instantiation: _ZN2yb5SliceC2EPKc
_ZN2yb5SliceC1EPKc
Line
Count
Source
81
4.19G
      : Slice(to_uchar_ptr(s), strlen(s)) {}
82
83
  // Create a slice that refers to the contents of the faststring.
84
  // Note that further appends to the faststring may invalidate this slice.
85
  Slice(const faststring &s) // NOLINT(runtime/explicit)
86
24.2M
      : Slice(s.data(), s.size()) {}
_ZN2yb5SliceC1ERKNS_10faststringE
Line
Count
Source
86
24.2M
      : Slice(s.data(), s.size()) {}
Unexecuted instantiation: _ZN2yb5SliceC2ERKNS_10faststringE
87
88
  Slice(const GStringPiece& s) // NOLINT(runtime/explicit)
89
1.01k
      : Slice(to_uchar_ptr(s.data()), s.size()) {}
Unexecuted instantiation: _ZN2yb5SliceC2ERK12GStringPiece
_ZN2yb5SliceC1ERK12GStringPiece
Line
Count
Source
89
1.01k
      : Slice(to_uchar_ptr(s.data()), s.size()) {}
90
91
  // Create a single slice from SliceParts using buf as storage.
92
  // buf must exist as long as the returned Slice exists.
93
  Slice(const SliceParts& parts, std::string* buf);
94
95
4.80G
  const char* cdata() const { return to_char_ptr(begin_); }
96
97
  // Return a pointer to the beginning of the referenced data
98
34.0G
  const uint8_t* data() const { return begin_; }
99
100
  // Return a mutable pointer to the beginning of the referenced data.
101
204k
  uint8_t *mutable_data() { return const_cast<uint8_t*>(begin_); }
102
103
2.21G
  const uint8_t* end() const { return end_; }
104
105
888M
  const char* cend() const { return to_char_ptr(end_); }
106
107
  // Return the length (in bytes) of the referenced data
108
96.3G
  size_t size() const { return end_ - begin_; }
109
110
  // Return true iff the length of the referenced data is zero
111
9.97G
  bool empty() const { return begin_ == end_; }
112
113
  template <class... Args>
114
179
  bool GreaterOrEqual(const Slice& arg0, Args&&... args) const {
115
179
    return !Less(arg0, std::forward<Args>(args)...);
116
179
  }
_ZNK2yb5Slice14GreaterOrEqualIJEEEbRKS0_DpOT_
Line
Count
Source
114
179
  bool GreaterOrEqual(const Slice& arg0, Args&&... args) const {
115
179
    return !Less(arg0, std::forward<Args>(args)...);
116
179
  }
Unexecuted instantiation: _ZNK2yb5Slice14GreaterOrEqualIJRKS0_EEEbS3_DpOT_
117
118
  template <class... Args>
119
2.42M
  bool Less(const Slice& arg0, Args&&... args) const {
120
2.42M
    return DoLess(arg0, std::forward<Args>(args)...);
121
2.42M
  }
_ZNK2yb5Slice4LessIJEEEbRKS0_DpOT_
Line
Count
Source
119
2.42M
  bool Less(const Slice& arg0, Args&&... args) const {
120
2.42M
    return DoLess(arg0, std::forward<Args>(args)...);
121
2.42M
  }
_ZNK2yb5Slice4LessIJS0_EEEbRKS0_DpOT_
Line
Count
Source
119
65
  bool Less(const Slice& arg0, Args&&... args) const {
120
65
    return DoLess(arg0, std::forward<Args>(args)...);
121
65
  }
_ZNK2yb5Slice4LessIJS0_S0_EEEbRKS0_DpOT_
Line
Count
Source
119
210
  bool Less(const Slice& arg0, Args&&... args) const {
120
210
    return DoLess(arg0, std::forward<Args>(args)...);
121
210
  }
_ZNK2yb5Slice4LessIJS0_S0_S0_EEEbRKS0_DpOT_
Line
Count
Source
119
450
  bool Less(const Slice& arg0, Args&&... args) const {
120
450
    return DoLess(arg0, std::forward<Args>(args)...);
121
450
  }
_ZNK2yb5Slice4LessIJS0_S0_S0_S0_EEEbRKS0_DpOT_
Line
Count
Source
119
672
  bool Less(const Slice& arg0, Args&&... args) const {
120
672
    return DoLess(arg0, std::forward<Args>(args)...);
121
672
  }
_ZNK2yb5Slice4LessIJS0_S0_S0_S0_S0_EEEbRKS0_DpOT_
Line
Count
Source
119
714
  bool Less(const Slice& arg0, Args&&... args) const {
120
714
    return DoLess(arg0, std::forward<Args>(args)...);
121
714
  }
_ZNK2yb5Slice4LessIJS0_S0_S0_S0_S0_S0_EEEbRKS0_DpOT_
Line
Count
Source
119
540
  bool Less(const Slice& arg0, Args&&... args) const {
120
540
    return DoLess(arg0, std::forward<Args>(args)...);
121
540
  }
_ZNK2yb5Slice4LessIJS0_S0_S0_S0_S0_S0_S0_EEEbRKS0_DpOT_
Line
Count
Source
119
285
  bool Less(const Slice& arg0, Args&&... args) const {
120
285
    return DoLess(arg0, std::forward<Args>(args)...);
121
285
  }
_ZNK2yb5Slice4LessIJS0_S0_S0_S0_S0_S0_S0_S0_EEEbRKS0_DpOT_
Line
Count
Source
119
100
  bool Less(const Slice& arg0, Args&&... args) const {
120
100
    return DoLess(arg0, std::forward<Args>(args)...);
121
100
  }
_ZNK2yb5Slice4LessIJS0_S0_S0_S0_S0_S0_S0_S0_S0_EEEbRKS0_DpOT_
Line
Count
Source
119
21
  bool Less(const Slice& arg0, Args&&... args) const {
120
21
    return DoLess(arg0, std::forward<Args>(args)...);
121
21
  }
_ZNK2yb5Slice4LessIJS0_S0_S0_S0_S0_S0_S0_S0_S0_S0_EEEbRKS0_DpOT_
Line
Count
Source
119
2
  bool Less(const Slice& arg0, Args&&... args) const {
120
2
    return DoLess(arg0, std::forward<Args>(args)...);
121
2
  }
Unexecuted instantiation: _ZNK2yb5Slice4LessIJRKS0_EEEbS3_DpOT_
122
123
  // Return the ith byte in the referenced data.
124
  // REQUIRES: n < size()
125
  uint8_t operator[](size_t n) const;
126
127
  // Change this slice to refer to an empty array
128
19.5M
  void clear() {
129
19.5M
    begin_ = to_uchar_ptr("");
130
19.5M
    end_ = begin_;
131
19.5M
  }
132
133
  // Drop the first "n" bytes from this slice.
134
  void remove_prefix(size_t n);
135
136
  Slice Prefix(size_t n) const;
137
138
  Slice WithoutPrefix(size_t n) const;
139
140
  // Drop the last "n" bytes from this slice.
141
  void remove_suffix(size_t n);
142
143
  Slice Suffix(size_t n) const;
144
145
  Slice WithoutSuffix(size_t n) const;
146
147
15.8M
  void CopyTo(void* buffer) const {
148
15.8M
    memcpy(buffer, begin_, size());
149
15.8M
  }
150
151
  // Truncate the slice to "n" bytes
152
  void truncate(size_t n);
153
154
  char consume_byte();
155
156
1.76G
  bool TryConsumeByte(char c) {
157
1.76G
    if (empty() || *begin_ != c) {
158
1.62G
      return false;
159
1.62G
    }
160
143M
    ++begin_;
161
143M
    return true;
162
143M
  }
163
164
20.9k
  char FirstByteOr(char def) {
165
20.9k
    return !empty() ? *begin_ : def;
166
20.9k
  }
167
168
  MUST_USE_RESULT Status consume_byte(char c);
169
170
  // Checks that this slice has size() = 'expected_size' and returns
171
  // STATUS(Corruption, ) otherwise.
172
  Status check_size(size_t expected_size) const;
173
174
  // Compare two slices and returns the offset of the first byte where they differ.
175
  size_t difference_offset(const Slice& b) const;
176
177
  void CopyToBuffer(std::string* buffer) const;
178
179
  // Return a string that contains the copy of the referenced data.
180
  std::string ToBuffer() const;
181
182
112M
  std::string ToString() const __attribute__ ((deprecated)) { return ToBuffer(); }
183
  std::string ToString(bool hex) const __attribute__ ((deprecated));
184
185
  std::string ToDebugString(size_t max_len = 0) const;
186
  std::string ToDebugHexString() const;
187
188
  // Three-way comparison.  Returns value:
189
  //   <  0 iff "*this" <  "b",
190
  //   == 0 iff "*this" == "b",
191
  //   >  0 iff "*this" >  "b"
192
  int compare(const Slice& b) const;
193
  int compare_prefix(const Slice& b) const;
194
195
  size_t hash() const noexcept;
196
197
  // Return true iff "x" is a prefix of "*this"
198
576M
  bool starts_with(const Slice& x) const {
199
576M
    return starts_with(x.data(), x.size());
200
576M
  }
201
202
576M
  bool starts_with(const uint8_t* data, size_t size) const {
203
576M
    return (this->size() >= size) && MemEqual(begin_, data, size);
204
576M
  }
205
206
304k
  bool starts_with(const char* data, size_t size) const {
207
304k
    return (this->size() >= size) && MemEqual(begin_, data, size);
208
304k
  }
209
210
43.7M
  bool starts_with(char c) const {
211
43.7M
    return (size() >= 1) && (*begin_ == c);
212
43.7M
  }
213
214
3.99M
  bool ends_with(const Slice& x) const {
215
3.99M
    size_t xsize = x.size();
216
3.99M
    return (size() >= xsize) && MemEqual(end_ - xsize, x.begin_, xsize);
217
3.99M
  }
218
219
293M
  bool ends_with(char c) const {
220
293M
    return (size() >= 1) && *(end_ - 1) == c;
221
293M
  }
222
223
  // Comparator struct, useful for ordered collections (like STL maps).
224
  struct Comparator {
225
4
    bool operator()(const Slice& a, const Slice& b) const {
226
4
      return a.compare(b) < 0;
227
4
    }
228
  };
229
230
  struct Hash {
231
273M
    size_t operator()(const Slice& a) const noexcept {
232
273M
      return a.hash();
233
273M
    }
234
  };
235
236
  // Relocates this slice's data into 'd' provided this isn't already the
237
  // case. It is assumed that 'd' is large enough to fit the data.
238
8
  void relocate(uint8_t* d) {
239
8
    if (begin_ != d) {
240
7
      size_t size = end_ - begin_;
241
7
      memcpy(d, begin_, size);
242
7
      begin_ = d;
243
7
      end_ = d + size;
244
7
    }
245
8
  }
246
247
377k
  size_t DynamicMemoryUsage() const { return 0; }
248
249
  // Return a Slice representing bytes for any type which is laid out contiguously in memory.
250
  template<class T, class = typename std::enable_if<std::is_pod<T>::value, void>::type>
251
20.4M
  static Slice FromPod(const T* data) {
252
20.4M
    return Slice(pointer_cast<const char*>(data), sizeof(*data));
253
20.4M
  }
254
255
 private:
256
  friend bool operator==(const Slice& x, const Slice& y);
257
258
1.19k
  bool DoLess() const {
259
1.19k
    return !empty();
260
1.19k
  }
261
262
  template <class... Args>
263
2.43M
  bool DoLess(const Slice& arg0, Args&&... args) const {
264
2.43M
    auto arg0_size = arg0.size();
265
2.43M
    if (size() < arg0_size) {
266
2.42M
      return compare(arg0) < 0;
267
2.42M
    }
268
269
16.9k
    int cmp = Slice(begin_, arg0_size).compare(arg0);
270
16.9k
    if (cmp != 0) {
271
1.41k
      return cmp < 0;
272
1.41k
    }
273
274
15.4k
    return Slice(begin_ + arg0_size, end_).DoLess(std::forward<Args>(args)...);
275
15.4k
  }
_ZNK2yb5Slice6DoLessIJEEEbRKS0_DpOT_
Line
Count
Source
263
2.42M
  bool DoLess(const Slice& arg0, Args&&... args) const {
264
2.42M
    auto arg0_size = arg0.size();
265
2.42M
    if (size() < arg0_size) {
266
2.42M
      return compare(arg0) < 0;
267
2.42M
    }
268
269
2.56k
    int cmp = Slice(begin_, arg0_size).compare(arg0);
270
2.56k
    if (cmp != 0) {
271
1.41k
      return cmp < 0;
272
1.41k
    }
273
274
1.14k
    return Slice(begin_ + arg0_size, end_).DoLess(std::forward<Args>(args)...);
275
1.14k
  }
_ZNK2yb5Slice6DoLessIJS0_EEEbRKS0_DpOT_
Line
Count
Source
263
3.05k
  bool DoLess(const Slice& arg0, Args&&... args) const {
264
3.05k
    auto arg0_size = arg0.size();
265
3.05k
    if (size() < arg0_size) {
266
0
      return compare(arg0) < 0;
267
0
    }
268
269
3.05k
    int cmp = Slice(begin_, arg0_size).compare(arg0);
270
3.05k
    if (cmp != 0) {
271
0
      return cmp < 0;
272
0
    }
273
274
3.05k
    return Slice(begin_ + arg0_size, end_).DoLess(std::forward<Args>(args)...);
275
3.05k
  }
_ZNK2yb5Slice6DoLessIJS0_S0_EEEbRKS0_DpOT_
Line
Count
Source
263
2.99k
  bool DoLess(const Slice& arg0, Args&&... args) const {
264
2.99k
    auto arg0_size = arg0.size();
265
2.99k
    if (size() < arg0_size) {
266
0
      return compare(arg0) < 0;
267
0
    }
268
269
2.99k
    int cmp = Slice(begin_, arg0_size).compare(arg0);
270
2.99k
    if (cmp != 0) {
271
0
      return cmp < 0;
272
0
    }
273
274
2.99k
    return Slice(begin_ + arg0_size, end_).DoLess(std::forward<Args>(args)...);
275
2.99k
  }
_ZNK2yb5Slice6DoLessIJS0_S0_S0_EEEbRKS0_DpOT_
Line
Count
Source
263
2.78k
  bool DoLess(const Slice& arg0, Args&&... args) const {
264
2.78k
    auto arg0_size = arg0.size();
265
2.78k
    if (size() < arg0_size) {
266
0
      return compare(arg0) < 0;
267
0
    }
268
269
2.78k
    int cmp = Slice(begin_, arg0_size).compare(arg0);
270
2.78k
    if (cmp != 0) {
271
0
      return cmp < 0;
272
0
    }
273
274
2.78k
    return Slice(begin_ + arg0_size, end_).DoLess(std::forward<Args>(args)...);
275
2.78k
  }
_ZNK2yb5Slice6DoLessIJS0_S0_S0_S0_EEEbRKS0_DpOT_
Line
Count
Source
263
2.33k
  bool DoLess(const Slice& arg0, Args&&... args) const {
264
2.33k
    auto arg0_size = arg0.size();
265
2.33k
    if (size() < arg0_size) {
266
0
      return compare(arg0) < 0;
267
0
    }
268
269
2.33k
    int cmp = Slice(begin_, arg0_size).compare(arg0);
270
2.33k
    if (cmp != 0) {
271
0
      return cmp < 0;
272
0
    }
273
274
2.33k
    return Slice(begin_ + arg0_size, end_).DoLess(std::forward<Args>(args)...);
275
2.33k
  }
_ZNK2yb5Slice6DoLessIJS0_S0_S0_S0_S0_EEEbRKS0_DpOT_
Line
Count
Source
263
1.66k
  bool DoLess(const Slice& arg0, Args&&... args) const {
264
1.66k
    auto arg0_size = arg0.size();
265
1.66k
    if (size() < arg0_size) {
266
0
      return compare(arg0) < 0;
267
0
    }
268
269
1.66k
    int cmp = Slice(begin_, arg0_size).compare(arg0);
270
1.66k
    if (cmp != 0) {
271
0
      return cmp < 0;
272
0
    }
273
274
1.66k
    return Slice(begin_ + arg0_size, end_).DoLess(std::forward<Args>(args)...);
275
1.66k
  }
_ZNK2yb5Slice6DoLessIJS0_S0_S0_S0_S0_S0_EEEbRKS0_DpOT_
Line
Count
Source
263
948
  bool DoLess(const Slice& arg0, Args&&... args) const {
264
948
    auto arg0_size = arg0.size();
265
948
    if (size() < arg0_size) {
266
0
      return compare(arg0) < 0;
267
0
    }
268
269
948
    int cmp = Slice(begin_, arg0_size).compare(arg0);
270
948
    if (cmp != 0) {
271
0
      return cmp < 0;
272
0
    }
273
274
948
    return Slice(begin_ + arg0_size, end_).DoLess(std::forward<Args>(args)...);
275
948
  }
_ZNK2yb5Slice6DoLessIJS0_S0_S0_S0_S0_S0_S0_EEEbRKS0_DpOT_
Line
Count
Source
263
408
  bool DoLess(const Slice& arg0, Args&&... args) const {
264
408
    auto arg0_size = arg0.size();
265
408
    if (size() < arg0_size) {
266
0
      return compare(arg0) < 0;
267
0
    }
268
269
408
    int cmp = Slice(begin_, arg0_size).compare(arg0);
270
408
    if (cmp != 0) {
271
0
      return cmp < 0;
272
0
    }
273
274
408
    return Slice(begin_ + arg0_size, end_).DoLess(std::forward<Args>(args)...);
275
408
  }
_ZNK2yb5Slice6DoLessIJS0_S0_S0_S0_S0_S0_S0_S0_EEEbRKS0_DpOT_
Line
Count
Source
263
123
  bool DoLess(const Slice& arg0, Args&&... args) const {
264
123
    auto arg0_size = arg0.size();
265
123
    if (size() < arg0_size) {
266
0
      return compare(arg0) < 0;
267
0
    }
268
269
123
    int cmp = Slice(begin_, arg0_size).compare(arg0);
270
123
    if (cmp != 0) {
271
0
      return cmp < 0;
272
0
    }
273
274
123
    return Slice(begin_ + arg0_size, end_).DoLess(std::forward<Args>(args)...);
275
123
  }
_ZNK2yb5Slice6DoLessIJS0_S0_S0_S0_S0_S0_S0_S0_S0_EEEbRKS0_DpOT_
Line
Count
Source
263
23
  bool DoLess(const Slice& arg0, Args&&... args) const {
264
23
    auto arg0_size = arg0.size();
265
23
    if (size() < arg0_size) {
266
0
      return compare(arg0) < 0;
267
0
    }
268
269
23
    int cmp = Slice(begin_, arg0_size).compare(arg0);
270
23
    if (cmp != 0) {
271
0
      return cmp < 0;
272
0
    }
273
274
23
    return Slice(begin_ + arg0_size, end_).DoLess(std::forward<Args>(args)...);
275
23
  }
_ZNK2yb5Slice6DoLessIJS0_S0_S0_S0_S0_S0_S0_S0_S0_S0_EEEbRKS0_DpOT_
Line
Count
Source
263
2
  bool DoLess(const Slice& arg0, Args&&... args) const {
264
2
    auto arg0_size = arg0.size();
265
2
    if (size() < arg0_size) {
266
0
      return compare(arg0) < 0;
267
0
    }
268
269
2
    int cmp = Slice(begin_, arg0_size).compare(arg0);
270
2
    if (cmp != 0) {
271
0
      return cmp < 0;
272
0
    }
273
274
2
    return Slice(begin_ + arg0_size, end_).DoLess(std::forward<Args>(args)...);
275
2
  }
Unexecuted instantiation: _ZNK2yb5Slice6DoLessIJRKS0_EEEbS3_DpOT_
276
277
1.34G
  static bool MemEqual(const void* a, const void* b, size_t n) {
278
1.34G
    return strings::memeq(a, b, n);
279
1.34G
  }
280
281
14.4G
  static int MemCompare(const void* a, const void* b, size_t n) {
282
14.4G
    return strings::fastmemcmp_inlined(a, b, n);
283
14.4G
  }
284
285
  const uint8_t* begin_;
286
  const uint8_t* end_;
287
288
  // Intentionally copyable
289
};
290
291
struct SliceParts {
292
  SliceParts(const Slice* _parts, int _num_parts) :
293
169M
      parts(_parts), num_parts(_num_parts) { }
294
2.84M
  SliceParts() : parts(nullptr), num_parts(0) {}
295
296
  template<size_t N>
297
  SliceParts(const std::array<Slice, N>& input) // NOLINT
298
130M
      : parts(input.data()), num_parts(N) {
299
130M
  }
_ZN2yb10SlicePartsC2ILm5EEERKNSt3__15arrayINS_5SliceEXT_EEE
Line
Count
Source
298
2
      : parts(input.data()), num_parts(N) {
299
2
  }
Unexecuted instantiation: _ZN2yb10SlicePartsC2ILm4EEERKNSt3__15arrayINS_5SliceEXT_EEE
Unexecuted instantiation: _ZN2yb10SlicePartsC2ILm6EEERKNSt3__15arrayINS_5SliceEXT_EEE
_ZN2yb10SlicePartsC2ILm2EEERKNSt3__15arrayINS_5SliceEXT_EEE
Line
Count
Source
298
81.6M
      : parts(input.data()), num_parts(N) {
299
81.6M
  }
_ZN2yb10SlicePartsC2ILm1EEERKNSt3__15arrayINS_5SliceEXT_EEE
Line
Count
Source
298
619
      : parts(input.data()), num_parts(N) {
299
619
  }
Unexecuted instantiation: _ZN2yb10SlicePartsC2ILm11EEERKNSt3__15arrayINS_5SliceEXT_EEE
_ZN2yb10SlicePartsC2ILm3EEERKNSt3__15arrayINS_5SliceEXT_EEE
Line
Count
Source
298
27.9M
      : parts(input.data()), num_parts(N) {
299
27.9M
  }
_ZN2yb10SlicePartsC2ILm7EEERKNSt3__15arrayINS_5SliceEXT_EEE
Line
Count
Source
298
20.4M
      : parts(input.data()), num_parts(N) {
299
20.4M
  }
Unexecuted instantiation: _ZN2yb10SlicePartsC2ILm10EEERKNSt3__15arrayINS_5SliceEXT_EEE
300
301
  std::string ToDebugHexString() const;
302
303
  // Sum of sizes of all slices.
304
  size_t SumSizes() const;
305
306
  // Copy content of all slice to specified buffer.
307
0
  void* CopyAllTo(void* out) const {
308
0
    return CopyAllTo(static_cast<char*>(out));
309
0
  }
310
311
  char* CopyAllTo(char* out) const;
312
313
  Slice TheOnlyPart() const;
314
315
  const Slice* parts;
316
  int num_parts;
317
};
318
319
988M
inline bool operator==(const Slice& x, const Slice& y) {
320
988M
  return ((x.size() == y.size()) &&
321
787M
          (Slice::MemEqual(x.data(), y.data(), x.size())));
322
988M
}
323
324
69.3M
inline bool operator!=(const Slice& x, const Slice& y) {
325
69.3M
  return !(x == y);
326
69.3M
}
327
328
12
inline std::ostream& operator<<(std::ostream& o, const Slice& s) {
329
12
  return o << s.ToDebugString(16); // should be enough for anyone...
330
12
}
331
332
14.3G
inline int Slice::compare(const Slice& b) const {
333
14.3G
  auto my_size = size();
334
14.3G
  auto b_size = b.size();
335
14.3G
  const size_t min_len = std::min(my_size, b_size);
336
14.3G
  int r = MemCompare(begin_, b.begin_, min_len);
337
14.3G
  if (r == 0) {
338
550M
    if (my_size < b_size) { return -1; }
339
512M
    if (my_size > b_size) { return 1; }
340
14.2G
  }
341
14.2G
  return r;
342
14.2G
}
343
344
3.65M
inline int Slice::compare_prefix(const Slice& b) const {
345
3.65M
  return Slice(begin_, std::min(size(), b.size())).compare(b);
346
3.65M
}
347
348
394M
inline size_t Slice::hash() const noexcept {
349
394M
  constexpr uint64_t kFnvOffset = 14695981039346656037ULL;
350
394M
  constexpr uint64_t kFnvPrime = 1099511628211ULL;
351
394M
  size_t result = kFnvOffset;
352
394M
  const uint8_t* e = end();
353
8.63G
  for (const uint8_t* i = begin_; i != e; ++i) {
354
8.23G
    result = (result * kFnvPrime) ^ *i;
355
8.23G
  }
356
394M
  return result;
357
394M
}
358
359
31.3M
inline size_t hash_value(const Slice& slice) {
360
31.3M
  return slice.hash();
361
31.3M
}
362
363
4
inline size_t Slice::difference_offset(const Slice& b) const {
364
4
  size_t off = 0;
365
4
  const size_t len = std::min(size(), b.size());
366
36
  for (; off < len; off++) {
367
32
    if (begin_[off] != b.begin_[off]) break;
368
32
  }
369
4
  return off;
370
4
}
371
372
// Can be used with source implicitly convertible to Slice, for example std::string.
373
75.5k
inline void CopyToBuffer(const Slice& source, std::string* dest) {
374
  // operator= or assign(const std::string&) will shrink the capacity on at least CentOS gcc
375
  // build, so we have to use assign(const char*, size_t) to preserve buffer capacity and avoid
376
  // unnecessary memory reallocations.
377
75.5k
  source.CopyToBuffer(dest);
378
75.5k
}
379
380
}  // namespace yb
381
382
namespace rocksdb {
383
384
typedef yb::Slice Slice;
385
typedef yb::SliceParts SliceParts;
386
387
}  // namespace rocksdb
388
389
#endif // YB_UTIL_SLICE_H_