Kudu C++ client API
 All Classes Namespaces 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 #include <assert.h>
11 #include <map>
12 #include <stddef.h>
13 #include <stdint.h>
14 #include <string.h>
15 #include <string>
16 
17 #ifdef KUDU_HEADERS_USE_RICH_SLICE
18 #include "kudu/gutil/strings/fastmem.h"
19 #include "kudu/gutil/strings/stringpiece.h"
20 #include "kudu/util/faststring.h"
21 #endif
22 #include "kudu/util/kudu_export.h"
23 
24 namespace kudu {
25 
26 class Status;
27 
43 class KUDU_EXPORT Slice {
44  public:
46  Slice() : data_(reinterpret_cast<const uint8_t *>("")),
47  size_(0) { }
48 
55  Slice(const uint8_t* d, size_t n) : data_(d), size_(n) { }
56 
63  Slice(const char* d, size_t n) :
64  data_(reinterpret_cast<const uint8_t *>(d)),
65  size_(n) { }
66 
71  Slice(const std::string& s) : // NOLINT(runtime/explicit)
72  data_(reinterpret_cast<const uint8_t *>(s.data())),
73  size_(s.size()) { }
74 
79  Slice(const char* s) : // NOLINT(runtime/explicit)
80  data_(reinterpret_cast<const uint8_t *>(s)),
81  size_(strlen(s)) { }
82 
83 #ifdef KUDU_HEADERS_USE_RICH_SLICE
84  Slice(const faststring &s) // NOLINT(runtime/explicit)
91  : data_(s.data()),
92  size_(s.size()) {
93  }
94 
99  Slice(const StringPiece& s) // NOLINT(runtime/explicit)
100  : data_(reinterpret_cast<const uint8_t*>(s.data())),
101  size_(s.size()) {
102  }
103 #endif
104 
106  const uint8_t* data() const { return data_; }
107 
109  uint8_t *mutable_data() { return const_cast<uint8_t *>(data_); }
110 
112  size_t size() const { return size_; }
113 
115  bool empty() const { return size_ == 0; }
116 
122  const uint8_t &operator[](size_t n) const {
123  assert(n < size());
124  return data_[n];
125  }
126 
128  void clear() {
129  data_ = reinterpret_cast<const uint8_t *>("");
130  size_ = 0;
131  }
132 
142  void remove_prefix(size_t n) {
143  assert(n <= size());
144  data_ += n;
145  size_ -= n;
146  }
147 
157  void truncate(size_t n) {
158  assert(n <= size());
159  size_ = n;
160  }
161 
166  Status check_size(size_t expected_size) const;
167 
169  std::string ToString() const;
170 
177  std::string ToDebugString(size_t max_len = 0) const;
178 
187  int compare(const Slice& b) const;
188 
193  bool starts_with(const Slice& x) const {
194  return ((size_ >= x.size_) &&
195  (MemEqual(data_, x.data_, x.size_)));
196  }
197 
199  struct Comparator {
207  bool operator()(const Slice& a, const Slice& b) const {
208  return a.compare(b) < 0;
209  }
210  };
211 
218  void relocate(uint8_t* d) {
219  if (data_ != d) {
220  memcpy(d, data_, size_);
221  data_ = d;
222  }
223  }
224 
225  private:
226  friend bool operator==(const Slice& x, const Slice& y);
227 
228  static bool MemEqual(const void* a, const void* b, size_t n) {
229 #ifdef KUDU_HEADERS_USE_RICH_SLICE
230  return strings::memeq(a, b, n);
231 #else
232  return memcmp(a, b, n) == 0;
233 #endif
234  }
235 
236  static int MemCompare(const void* a, const void* b, size_t n) {
237 #ifdef KUDU_HEADERS_USE_RICH_SLICE
238  return strings::fastmemcmp_inlined(a, b, n);
239 #else
240  return memcmp(a, b, n);
241 #endif
242  }
243 
244  const uint8_t* data_;
245  size_t size_;
246 
247  // Intentionally copyable
248 };
249 
257 inline bool operator==(const Slice& x, const Slice& y) {
258  return ((x.size() == y.size()) &&
259  (Slice::MemEqual(x.data(), y.data(), x.size())));
260 }
261 
269 inline bool operator!=(const Slice& x, const Slice& y) {
270  return !(x == y);
271 }
272 
280 inline std::ostream& operator<<(std::ostream& o, const Slice& s) {
281  return o << s.ToDebugString(16); // should be enough for anyone...
282 }
283 
284 inline int Slice::compare(const Slice& b) const {
285  const int min_len = (size_ < b.size_) ? size_ : b.size_;
286  int r = MemCompare(data_, b.data_, min_len);
287  if (r == 0) {
288  if (size_ < b.size_) r = -1;
289  else if (size_ > b.size_) r = +1;
290  }
291  return r;
292 }
293 
309 template <typename T>
310 struct SliceMap {
312  typedef std::map<Slice, T, Slice::Comparator> type;
313 };
314 
315 } // namespace kudu
316 
317 #endif // KUDU_UTIL_SLICE_H_
A representation of an operation's outcome.
Definition: status.h:106
void relocate(uint8_t *d)
Definition: slice.h:218
Slice(const char *s)
Definition: slice.h:79
bool starts_with(const Slice &x) const
Definition: slice.h:193
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:312
bool operator()(const Slice &a, const Slice &b) const
Definition: slice.h:207
void clear()
Change this slice to refer to an empty array.
Definition: slice.h:128
const uint8_t & operator[](size_t n) const
Definition: slice.h:122
Comparator struct, useful for ordered collections (like STL maps).
Definition: slice.h:199
void truncate(size_t n)
Definition: slice.h:157
STL map whose keys are Slices.
Definition: slice.h:310
A wrapper around externally allocated data.
Definition: slice.h:43
size_t size() const
Definition: slice.h:112
Slice(const uint8_t *d, size_t n)
Definition: slice.h:55
Slice(const char *d, size_t n)
Definition: slice.h:63
uint8_t * mutable_data()
Definition: slice.h:109
const uint8_t * data() const
Definition: slice.h:106
void remove_prefix(size_t n)
Definition: slice.h:142
Slice(const std::string &s)
Definition: slice.h:71
std::ostream & operator<<(std::ostream &o, const Slice &s)
Definition: slice.h:280
bool operator==(const Slice &x, const Slice &y)
Definition: slice.h:257
int compare(const Slice &b) const
Definition: slice.h:284
bool operator!=(const Slice &x, const Slice &y)
Definition: slice.h:269
Slice()
Create an empty slice.
Definition: slice.h:46
bool empty() const
Definition: slice.h:115