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 <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
92  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 std::ostream& operator<<(std::ostream& o, const Slice& s) {
289  return o << s.ToDebugString(16); // should be enough for anyone...
290 }
291 
292 inline int Slice::compare(const Slice& b) const {
293  const int min_len = (size_ < b.size_) ? size_ : b.size_;
294  int r = MemCompare(data_, b.data_, min_len);
295  if (r == 0) {
296  if (size_ < b.size_) r = -1;
297  else if (size_ > b.size_) r = +1;
298  }
299  return r;
300 }
301 
302 // We don't run TSAN on this function because it makes it really slow and causes some
303 // test timeouts. This is only used on local buffers anyway, so we don't lose much
304 // by not checking it.
305 #ifdef KUDU_HEADERS_NO_STUBS
306 ATTRIBUTE_NO_SANITIZE_THREAD
307 #endif
308 bool IsAllZeros(const Slice& s);
309 
325 template <typename T>
326 struct SliceMap {
328  typedef std::map<Slice, T, Slice::Comparator> type;
329 };
330 
331 } // namespace kudu
332 
333 #endif // KUDU_UTIL_SLICE_H_
A representation of an operation&#39;s outcome.
Definition: status.h:165
Definition: callbacks.h:28
void relocate(uint8_t *d)
Definition: slice.h:226
Slice(const char *s)
Definition: slice.h:87
bool starts_with(const Slice &x) const
Definition: slice.h:201
std::string ToDebugString(size_t max_len=0) const
std::map< Slice, T, Slice::Comparator > type
A handy typedef for the slice map with appropriate comparison operator.
Definition: slice.h:328
bool operator()(const Slice &a, const Slice &b) const
Definition: slice.h:215
void clear()
Change this slice to refer to an empty array.
Definition: slice.h:136
const uint8_t & operator[](size_t n) const
Definition: slice.h:130
Comparator struct, useful for ordered collections (like STL maps).
Definition: slice.h:207
void truncate(size_t n)
Definition: slice.h:165
STL map whose keys are Slices.
Definition: slice.h:326
A wrapper around externally allocated data.
Definition: slice.h:51
size_t size() const
Definition: slice.h:120
Slice(const uint8_t *d, size_t n)
Definition: slice.h:63
Slice(const char *d, size_t n)
Definition: slice.h:71
uint8_t * mutable_data()
Definition: slice.h:117
const uint8_t * data() const
Definition: slice.h:114
void remove_prefix(size_t n)
Definition: slice.h:150
Slice(const std::string &s)
Definition: slice.h:79
int compare(const Slice &b) const
Definition: slice.h:292
Slice()
Create an empty slice.
Definition: slice.h:54
bool empty() const
Definition: slice.h:123