00001
00002
00003
00004
00005
00006
00007 #ifndef KUDU_UTIL_SLICE_H_
00008 #define KUDU_UTIL_SLICE_H_
00009
00010 #include <assert.h>
00011 #include <map>
00012 #include <stddef.h>
00013 #include <stdint.h>
00014 #include <string.h>
00015 #include <string>
00016
00017 #ifdef KUDU_HEADERS_USE_RICH_SLICE
00018 #include "kudu/gutil/strings/fastmem.h"
00019 #include "kudu/gutil/strings/stringpiece.h"
00020 #include "kudu/util/faststring.h"
00021 #endif
00022 #include "kudu/util/kudu_export.h"
00023
00024 namespace kudu {
00025
00026 class Status;
00027
00043 class KUDU_EXPORT Slice {
00044 public:
00046 Slice() : data_(reinterpret_cast<const uint8_t *>("")),
00047 size_(0) { }
00048
00055 Slice(const uint8_t* d, size_t n) : data_(d), size_(n) { }
00056
00063 Slice(const char* d, size_t n) :
00064 data_(reinterpret_cast<const uint8_t *>(d)),
00065 size_(n) { }
00066
00071 Slice(const std::string& s) :
00072 data_(reinterpret_cast<const uint8_t *>(s.data())),
00073 size_(s.size()) { }
00074
00079 Slice(const char* s) :
00080 data_(reinterpret_cast<const uint8_t *>(s)),
00081 size_(strlen(s)) { }
00082
00083 #ifdef KUDU_HEADERS_USE_RICH_SLICE
00090 Slice(const faststring &s) // NOLINT(runtime/explicit)
00091 : data_(s.data()),
00092 size_(s.size()) {
00093 }
00094
00099 Slice(const StringPiece& s)
00100 : data_(reinterpret_cast<const uint8_t*>(s.data())),
00101 size_(s.size()) {
00102 }
00103 #endif
00104
00106 const uint8_t* data() const { return data_; }
00107
00109 uint8_t *mutable_data() { return const_cast<uint8_t *>(data_); }
00110
00112 size_t size() const { return size_; }
00113
00115 bool empty() const { return size_ == 0; }
00116
00122 const uint8_t &operator[](size_t n) const {
00123 assert(n < size());
00124 return data_[n];
00125 }
00126
00128 void clear() {
00129 data_ = reinterpret_cast<const uint8_t *>("");
00130 size_ = 0;
00131 }
00132
00142 void remove_prefix(size_t n) {
00143 assert(n <= size());
00144 data_ += n;
00145 size_ -= n;
00146 }
00147
00157 void truncate(size_t n) {
00158 assert(n <= size());
00159 size_ = n;
00160 }
00161
00166 Status check_size(size_t expected_size) const;
00167
00169 std::string ToString() const;
00170
00177 std::string ToDebugString(size_t max_len = 0) const;
00178
00187 int compare(const Slice& b) const;
00188
00193 bool starts_with(const Slice& x) const {
00194 return ((size_ >= x.size_) &&
00195 (MemEqual(data_, x.data_, x.size_)));
00196 }
00197
00199 struct Comparator {
00207 bool operator()(const Slice& a, const Slice& b) const {
00208 return a.compare(b) < 0;
00209 }
00210 };
00211
00218 void relocate(uint8_t* d) {
00219 if (data_ != d) {
00220 memcpy(d, data_, size_);
00221 data_ = d;
00222 }
00223 }
00224
00225 private:
00226 friend bool operator==(const Slice& x, const Slice& y);
00227
00228 static bool MemEqual(const void* a, const void* b, size_t n) {
00229 #ifdef KUDU_HEADERS_USE_RICH_SLICE
00230 return strings::memeq(a, b, n);
00231 #else
00232 return memcmp(a, b, n) == 0;
00233 #endif
00234 }
00235
00236 static int MemCompare(const void* a, const void* b, size_t n) {
00237 #ifdef KUDU_HEADERS_USE_RICH_SLICE
00238 return strings::fastmemcmp_inlined(a, b, n);
00239 #else
00240 return memcmp(a, b, n);
00241 #endif
00242 }
00243
00244 const uint8_t* data_;
00245 size_t size_;
00246
00247
00248 };
00249
00257 inline bool operator==(const Slice& x, const Slice& y) {
00258 return ((x.size() == y.size()) &&
00259 (Slice::MemEqual(x.data(), y.data(), x.size())));
00260 }
00261
00269 inline bool operator!=(const Slice& x, const Slice& y) {
00270 return !(x == y);
00271 }
00272
00280 inline std::ostream& operator<<(std::ostream& o, const Slice& s) {
00281 return o << s.ToDebugString(16);
00282 }
00283
00284 inline int Slice::compare(const Slice& b) const {
00285 const int min_len = (size_ < b.size_) ? size_ : b.size_;
00286 int r = MemCompare(data_, b.data_, min_len);
00287 if (r == 0) {
00288 if (size_ < b.size_) r = -1;
00289 else if (size_ > b.size_) r = +1;
00290 }
00291 return r;
00292 }
00293
00309 template <typename T>
00310 struct SliceMap {
00312 typedef std::map<Slice, T, Slice::Comparator> type;
00313 };
00314
00315 }
00316
00317 #endif // KUDU_UTIL_SLICE_H_