Kudu C++ client API
All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
slice.h
1 //
2 // Copyright (c) 2011 The LevelDB Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file. See the AUTHORS file for names of contributors.
5 //
6 
7 #ifndef KUDU_UTIL_SLICE_H_
8 #define KUDU_UTIL_SLICE_H_
9 
10 // NOTE: using stdint.h instead of cstdint because this file is supposed
11 // to be processed by a compiler lacking C++11 support.
12 #include <stdint.h>
13 
14 #include <cassert>
15 #include <cstddef>
16 #include <cstring>
17 #include <iosfwd>
18 #include <map>
19 #include <ostream>
20 #include <string>
21 
22 #ifdef KUDU_HEADERS_USE_RICH_SLICE
23 #include "kudu/gutil/strings/fastmem.h"
24 #include "kudu/gutil/strings/stringpiece.h"
25 #include "kudu/util/faststring.h"
26 #endif
27 #ifdef KUDU_HEADERS_NO_STUBS
28 #include "kudu/gutil/port.h"
29 #endif
30 #include "kudu/util/kudu_export.h"
31 
32 namespace kudu {
33 
34 class Status;
35 
51 class KUDU_EXPORT Slice {
52  public:
54  Slice() : data_(reinterpret_cast<const uint8_t *>("")),
55  size_(0) { }
56 
63  Slice(const uint8_t* d, size_t n) : data_(d), size_(n) { }
64 
71  Slice(const char* d, size_t n) :
72  data_(reinterpret_cast<const uint8_t *>(d)),
73  size_(n) { }
74 
79  Slice(const std::string& s) : // NOLINT(runtime/explicit)
80  data_(reinterpret_cast<const uint8_t *>(s.data())),
81  size_(s.size()) { }
82 
87  Slice(const char* s) : // NOLINT(runtime/explicit)
88  data_(reinterpret_cast<const uint8_t *>(s)),
89  size_(strlen(s)) { }
90 
91 #ifdef KUDU_HEADERS_USE_RICH_SLICE
98  Slice(const faststring &s) // NOLINT(runtime/explicit)
99  : data_(s.data()),
100  size_(s.size()) {
101  }
102 
107  Slice(const StringPiece& s) // NOLINT(runtime/explicit)
108  : data_(reinterpret_cast<const uint8_t*>(s.data())),
109  size_(s.size()) {
110  }
111 #endif
112 
114  const uint8_t* data() const { return data_; }
115 
117  uint8_t *mutable_data() { return const_cast<uint8_t *>(data_); }
118 
120  size_t size() const { return size_; }
121 
123  bool empty() const { return size_ == 0; }
124 
130  const uint8_t &operator[](size_t n) const {
131  assert(n < size());
132  return data_[n];
133  }
134 
136  void clear() {
137  data_ = reinterpret_cast<const uint8_t *>("");
138  size_ = 0;
139  }
140 
150  void remove_prefix(size_t n) {
151  assert(n <= size());
152  data_ += n;
153  size_ -= n;
154  }
155 
165  void truncate(size_t n) {
166  assert(n <= size());
167  size_ = n;
168  }
169 
174  Status check_size(size_t expected_size) const;
175 
177  std::string ToString() const;
178 
185  std::string ToDebugString(size_t max_len = 0) const;
186 
195  int compare(const Slice& b) const;
196 
201  bool starts_with(const Slice& x) const {
202  return ((size_ >= x.size_) &&
203  (MemEqual(data_, x.data_, x.size_)));
204  }
205 
207  struct Comparator {
215  bool operator()(const Slice& a, const Slice& b) const {
216  return a.compare(b) < 0;
217  }
218  };
219 
226  void relocate(uint8_t* d) {
227  if (data_ != d) {
228  memcpy(d, data_, size_);
229  data_ = d;
230  }
231  }
232 
233  private:
234  friend bool operator==(const Slice& x, const Slice& y);
235 
236  static bool MemEqual(const void* a, const void* b, size_t n) {
237 #ifdef KUDU_HEADERS_USE_RICH_SLICE
238  return strings::memeq(a, b, n);
239 #else
240  return memcmp(a, b, n) == 0;
241 #endif
242  }
243 
244  static int MemCompare(const void* a, const void* b, size_t n) {
245 #ifdef KUDU_HEADERS_USE_RICH_SLICE
246  return strings::fastmemcmp_inlined(a, b, n);
247 #else
248  return memcmp(a, b, n);
249 #endif
250  }
251 
252  const uint8_t* data_;
253  size_t size_;
254 
255  // Intentionally copyable
256 };
257 
265 inline bool operator==(const Slice& x, const Slice& y) {
266  return ((x.size() == y.size()) &&
267  (Slice::MemEqual(x.data(), y.data(), x.size())));
268 }
269 
277 inline bool operator!=(const Slice& x, const Slice& y) {
278  return !(x == y);
279 }
280 
288 inline bool operator<(const Slice& x, const Slice& y) {
289  return x.compare(y) < 0;
290 }
291 
299 inline bool operator>(const Slice& x, const Slice& y) {
300  return x.compare(y) > 0;
301 }
302 
310 inline bool operator>=(const Slice& x, const Slice& y) {
311  return x.compare(y) >= 0;
312 }
313 
321 inline bool operator<=(const Slice& x, const Slice& y) {
322  return x.compare(y) <= 0;
323 }
324 
332 inline std::ostream& operator<<(std::ostream& o, const Slice& s) {
333  return o << s.ToDebugString(16); // should be enough for anyone...
334 }
335 
336 inline int Slice::compare(const Slice& b) const {
337  const size_t min_len = (size_ < b.size_) ? size_ : b.size_;
338  const int r = MemCompare(data_, b.data_, min_len);
339  if (r != 0) {
340  return r;
341  }
342  if (size_ < b.size_) {
343  return -1;
344  }
345  if (size_ > b.size_) {
346  return 1;
347  }
348  return 0;
349 }
350 
351 // We don't run TSAN on this function because it makes it really slow and causes some
352 // test timeouts. This is only used on local buffers anyway, so we don't lose much
353 // by not checking it.
354 #ifdef KUDU_HEADERS_NO_STUBS
355 ATTRIBUTE_NO_SANITIZE_THREAD
356 #endif
357 bool IsAllZeros(const Slice& s);
358 
374 template <typename T>
375 struct SliceMap {
377  typedef std::map<Slice, T, Slice::Comparator> type;
378 };
379 
380 } // namespace kudu
381 
382 #endif // KUDU_UTIL_SLICE_H_
A wrapper around externally allocated data.
Definition: slice.h:51
void remove_prefix(size_t n)
Definition: slice.h:150
std::string ToString() const
bool empty() const
Definition: slice.h:123
Slice(const std::string &s)
Definition: slice.h:79
void truncate(size_t n)
Definition: slice.h:165
uint8_t * mutable_data()
Definition: slice.h:117
Status check_size(size_t expected_size) const
void relocate(uint8_t *d)
Definition: slice.h:226
const uint8_t & operator[](size_t n) const
Definition: slice.h:130
int compare(const Slice &b) const
Definition: slice.h:336
Slice(const uint8_t *d, size_t n)
Definition: slice.h:63
Slice(const char *d, size_t n)
Definition: slice.h:71
const uint8_t * data() const
Definition: slice.h:114
Slice()
Create an empty slice.
Definition: slice.h:54
bool starts_with(const Slice &x) const
Definition: slice.h:201
std::string ToDebugString(size_t max_len=0) const
Slice(const char *s)
Definition: slice.h:87
size_t size() const
Definition: slice.h:120
void clear()
Change this slice to refer to an empty array.
Definition: slice.h:136
A representation of an operation's outcome.
Definition: status.h:165
STL map whose keys are Slices.
Definition: slice.h:375
std::map< Slice, T, Slice::Comparator > type
A handy typedef for the slice map with appropriate comparison operator.
Definition: slice.h:377
Comparator struct, useful for ordered collections (like STL maps).
Definition: slice.h:207
bool operator()(const Slice &a, const Slice &b) const
Definition: slice.h:215