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 <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 #include "kudu/util/kudu_export.h"
27 
28 namespace kudu {
29 
30 class Status;
31 
47 class KUDU_EXPORT Slice {
48  public:
50  Slice() : data_(reinterpret_cast<const uint8_t *>("")),
51  size_(0) { }
52 
59  Slice(const uint8_t* d, size_t n) : data_(d), size_(n) { }
60 
67  Slice(const char* d, size_t n) :
68  data_(reinterpret_cast<const uint8_t *>(d)),
69  size_(n) { }
70 
75  Slice(const std::string& s) : // NOLINT(runtime/explicit)
76  data_(reinterpret_cast<const uint8_t *>(s.data())),
77  size_(s.size()) { }
78 
83  Slice(const char* s) : // NOLINT(runtime/explicit)
84  data_(reinterpret_cast<const uint8_t *>(s)),
85  size_(strlen(s)) { }
86 
87 #ifdef KUDU_HEADERS_USE_RICH_SLICE
88  Slice(const faststring &s) // NOLINT(runtime/explicit)
95  : data_(s.data()),
96  size_(s.size()) {
97  }
98 
103  Slice(const StringPiece& s) // NOLINT(runtime/explicit)
104  : data_(reinterpret_cast<const uint8_t*>(s.data())),
105  size_(s.size()) {
106  }
107 #endif
108 
110  const uint8_t* data() const { return data_; }
111 
113  uint8_t *mutable_data() { return const_cast<uint8_t *>(data_); }
114 
116  size_t size() const { return size_; }
117 
119  bool empty() const { return size_ == 0; }
120 
126  const uint8_t &operator[](size_t n) const {
127  assert(n < size());
128  return data_[n];
129  }
130 
132  void clear() {
133  data_ = reinterpret_cast<const uint8_t *>("");
134  size_ = 0;
135  }
136 
146  void remove_prefix(size_t n) {
147  assert(n <= size());
148  data_ += n;
149  size_ -= n;
150  }
151 
161  void truncate(size_t n) {
162  assert(n <= size());
163  size_ = n;
164  }
165 
170  Status check_size(size_t expected_size) const;
171 
173  std::string ToString() const;
174 
181  std::string ToDebugString(size_t max_len = 0) const;
182 
191  int compare(const Slice& b) const;
192 
197  bool starts_with(const Slice& x) const {
198  return ((size_ >= x.size_) &&
199  (MemEqual(data_, x.data_, x.size_)));
200  }
201 
203  struct Comparator {
211  bool operator()(const Slice& a, const Slice& b) const {
212  return a.compare(b) < 0;
213  }
214  };
215 
222  void relocate(uint8_t* d) {
223  if (data_ != d) {
224  memcpy(d, data_, size_);
225  data_ = d;
226  }
227  }
228 
229  private:
230  friend bool operator==(const Slice& x, const Slice& y);
231 
232  static bool MemEqual(const void* a, const void* b, size_t n) {
233 #ifdef KUDU_HEADERS_USE_RICH_SLICE
234  return strings::memeq(a, b, n);
235 #else
236  return memcmp(a, b, n) == 0;
237 #endif
238  }
239 
240  static int MemCompare(const void* a, const void* b, size_t n) {
241 #ifdef KUDU_HEADERS_USE_RICH_SLICE
242  return strings::fastmemcmp_inlined(a, b, n);
243 #else
244  return memcmp(a, b, n);
245 #endif
246  }
247 
248  const uint8_t* data_;
249  size_t size_;
250 
251  // Intentionally copyable
252 };
253 
261 inline bool operator==(const Slice& x, const Slice& y) {
262  return ((x.size() == y.size()) &&
263  (Slice::MemEqual(x.data(), y.data(), x.size())));
264 }
265 
273 inline bool operator!=(const Slice& x, const Slice& y) {
274  return !(x == y);
275 }
276 
284 inline std::ostream& operator<<(std::ostream& o, const Slice& s) {
285  return o << s.ToDebugString(16); // should be enough for anyone...
286 }
287 
288 inline int Slice::compare(const Slice& b) const {
289  const int min_len = (size_ < b.size_) ? size_ : b.size_;
290  int r = MemCompare(data_, b.data_, min_len);
291  if (r == 0) {
292  if (size_ < b.size_) r = -1;
293  else if (size_ > b.size_) r = +1;
294  }
295  return r;
296 }
297 
313 template <typename T>
314 struct SliceMap {
316  typedef std::map<Slice, T, Slice::Comparator> type;
317 };
318 
319 } // namespace kudu
320 
321 #endif // KUDU_UTIL_SLICE_H_
A representation of an operation&#39;s outcome.
Definition: status.h:135
void relocate(uint8_t *d)
Definition: slice.h:222
Slice(const char *s)
Definition: slice.h:83
bool starts_with(const Slice &x) const
Definition: slice.h:197
std::map< Slice, T, Slice::Comparator > type
A handy typedef for the slice map with appropriate comparison operator.
Definition: slice.h:316
bool operator()(const Slice &a, const Slice &b) const
Definition: slice.h:211
void clear()
Change this slice to refer to an empty array.
Definition: slice.h:132
const uint8_t & operator[](size_t n) const
Definition: slice.h:126
Comparator struct, useful for ordered collections (like STL maps).
Definition: slice.h:203
void truncate(size_t n)
Definition: slice.h:161
STL map whose keys are Slices.
Definition: slice.h:314
A wrapper around externally allocated data.
Definition: slice.h:47
size_t size() const
Definition: slice.h:116
Slice(const uint8_t *d, size_t n)
Definition: slice.h:59
Slice(const char *d, size_t n)
Definition: slice.h:67
uint8_t * mutable_data()
Definition: slice.h:113
const uint8_t * data() const
Definition: slice.h:110
void remove_prefix(size_t n)
Definition: slice.h:146
Slice(const std::string &s)
Definition: slice.h:75
int compare(const Slice &b) const
Definition: slice.h:288
Slice()
Create an empty slice.
Definition: slice.h:50
bool empty() const
Definition: slice.h:119