Kudu C++ client API
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 <string>
20 
21 #ifdef KUDU_HEADERS_USE_RICH_SLICE
22 #include "kudu/gutil/strings/fastmem.h"
23 #include "kudu/gutil/strings/stringpiece.h"
24 #include "kudu/util/faststring.h"
25 #endif
26 #ifdef KUDU_HEADERS_NO_STUBS
27 #include "kudu/gutil/port.h"
28 #endif
29 #include "kudu/util/kudu_export.h"
30 
31 namespace kudu {
32 
33 class Status;
34 
50 class KUDU_EXPORT Slice {
51  public:
53  Slice() : data_(reinterpret_cast<const uint8_t *>("")),
54  size_(0) { }
55 
62  Slice(const uint8_t* d, size_t n) : data_(d), size_(n) { }
63 
70  Slice(const char* d, size_t n) :
71  data_(reinterpret_cast<const uint8_t *>(d)),
72  size_(n) { }
73 
78  Slice(const std::string& s) : // NOLINT(runtime/explicit)
79  data_(reinterpret_cast<const uint8_t *>(s.data())),
80  size_(s.size()) { }
81 
86  Slice(const char* s) : // NOLINT(runtime/explicit)
87  data_(reinterpret_cast<const uint8_t *>(s)),
88  size_(strlen(s)) { }
89 
90 #ifdef KUDU_HEADERS_USE_RICH_SLICE
91  Slice(const faststring &s) // NOLINT(runtime/explicit)
98  : data_(s.data()),
99  size_(s.size()) {
100  }
101 
106  Slice(const StringPiece& s) // NOLINT(runtime/explicit)
107  : data_(reinterpret_cast<const uint8_t*>(s.data())),
108  size_(s.size()) {
109  }
110 #endif
111 
113  const uint8_t* data() const { return data_; }
114 
116  uint8_t *mutable_data() { return const_cast<uint8_t *>(data_); }
117 
119  size_t size() const { return size_; }
120 
122  bool empty() const { return size_ == 0; }
123 
129  const uint8_t &operator[](size_t n) const {
130  assert(n < size());
131  return data_[n];
132  }
133 
135  void clear() {
136  data_ = reinterpret_cast<const uint8_t *>("");
137  size_ = 0;
138  }
139 
149  void remove_prefix(size_t n) {
150  assert(n <= size());
151  data_ += n;
152  size_ -= n;
153  }
154 
164  void truncate(size_t n) {
165  assert(n <= size());
166  size_ = n;
167  }
168 
173  Status check_size(size_t expected_size) const;
174 
176  std::string ToString() const;
177 
184  std::string ToDebugString(size_t max_len = 0) const;
185 
194  int compare(const Slice& b) const;
195 
200  bool starts_with(const Slice& x) const {
201  return ((size_ >= x.size_) &&
202  (MemEqual(data_, x.data_, x.size_)));
203  }
204 
206  struct Comparator {
214  bool operator()(const Slice& a, const Slice& b) const {
215  return a.compare(b) < 0;
216  }
217  };
218 
225  void relocate(uint8_t* d) {
226  if (data_ != d) {
227  memcpy(d, data_, size_);
228  data_ = d;
229  }
230  }
231 
232  private:
233  friend bool operator==(const Slice& x, const Slice& y);
234 
235  static bool MemEqual(const void* a, const void* b, size_t n) {
236 #ifdef KUDU_HEADERS_USE_RICH_SLICE
237  return strings::memeq(a, b, n);
238 #else
239  return memcmp(a, b, n) == 0;
240 #endif
241  }
242 
243  static int MemCompare(const void* a, const void* b, size_t n) {
244 #ifdef KUDU_HEADERS_USE_RICH_SLICE
245  return strings::fastmemcmp_inlined(a, b, n);
246 #else
247  return memcmp(a, b, n);
248 #endif
249  }
250 
251  const uint8_t* data_;
252  size_t size_;
253 
254  // Intentionally copyable
255 };
256 
264 inline bool operator==(const Slice& x, const Slice& y) {
265  return ((x.size() == y.size()) &&
266  (Slice::MemEqual(x.data(), y.data(), x.size())));
267 }
268 
276 inline bool operator!=(const Slice& x, const Slice& y) {
277  return !(x == y);
278 }
279 
287 inline std::ostream& operator<<(std::ostream& o, const Slice& s) {
288  return o << s.ToDebugString(16); // should be enough for anyone...
289 }
290 
291 inline int Slice::compare(const Slice& b) const {
292  const int min_len = (size_ < b.size_) ? size_ : b.size_;
293  int r = MemCompare(data_, b.data_, min_len);
294  if (r == 0) {
295  if (size_ < b.size_) r = -1;
296  else if (size_ > b.size_) r = +1;
297  }
298  return r;
299 }
300 
301 // We don't run TSAN on this function because it makes it really slow and causes some
302 // test timeouts. This is only used on local buffers anyway, so we don't lose much
303 // by not checking it.
304 #ifdef KUDU_HEADERS_NO_STUBS
305 ATTRIBUTE_NO_SANITIZE_THREAD
306 #endif
307 bool IsAllZeros(const Slice& s);
308 
324 template <typename T>
325 struct SliceMap {
327  typedef std::map<Slice, T, Slice::Comparator> type;
328 };
329 
330 } // namespace kudu
331 
332 #endif // KUDU_UTIL_SLICE_H_
Slice(const std::string &s)
Definition: slice.h:78
Comparator struct, useful for ordered collections (like STL maps).
Definition: slice.h:206
Definition: callbacks.h:28
bool starts_with(const Slice &x) const
Definition: slice.h:200
STL map whose keys are Slices.
Definition: slice.h:325
bool empty() const
Definition: slice.h:122
size_t size() const
Definition: slice.h:119
void clear()
Change this slice to refer to an empty array.
Definition: slice.h:135
int compare(const Slice &b) const
Definition: slice.h:291
Slice(const char *s)
Definition: slice.h:86
bool operator()(const Slice &a, const Slice &b) const
Definition: slice.h:214
Slice(const char *d, size_t n)
Definition: slice.h:70
void truncate(size_t n)
Definition: slice.h:164
std::map< Slice, T, Slice::Comparator > type
A handy typedef for the slice map with appropriate comparison operator.
Definition: slice.h:327
Slice(const uint8_t *d, size_t n)
Definition: slice.h:62
Slice()
Create an empty slice.
Definition: slice.h:53
A wrapper around externally allocated data.
Definition: slice.h:50
const uint8_t * data() const
Definition: slice.h:113
A representation of an operation&#39;s outcome.
Definition: status.h:145
void remove_prefix(size_t n)
Definition: slice.h:149
uint8_t * mutable_data()
Definition: slice.h:116
void relocate(uint8_t *d)
Definition: slice.h:225
std::string ToDebugString(size_t max_len=0) const
const uint8_t & operator[](size_t n) const
Definition: slice.h:129