Slice是一种包含字节长度与指针(指定一个外部字节数组)的简单数据结构。Leveldb以Slice作为基本数据结构来存储Key和data,Slice对数据字节的大小没有限制。
class Slice {
public:
const char* data() const { return data_; }
size_t size() const { return size_; }
bool empty() const { return size_ == 0; }
private:
const char* data_;
size_t size_;
};之所以采用Slice而不是string有如下原因:
- Slice作为返回值只需要返回长度与指针,不需要复制长度较长的key和value。
- Slice存储的有长度,不以
\0作为结束,可以存储值为\0的数据。
为了便于使用,提供了string与Slice进行转换的构造函数。
class Slice {
public:
Slice(): data_(""), size_(0) {}
Slice(const char* d, size_t n) : data_(d), size_(n) {}
Slice(const char* d): data_(d), size_(strlen(d)) {}
Slice(const std::string& s): data_(s.data()), size_(s.size()) {}
Slice(const Slice&)=default;
Slice& operator=(const Slice&)=default;
std::string ToString() const { return std::string(data_, size_); }
...
private:
...
}Slice作为key的时候需要进行比较,所以提供了进行比较的compare函数,并重载了!=, ==函数。
class Slice {
public:
int compare(const Slice& b) const;
};
inline int Slice::compare(const Slice& rhs) const {
const size_t min_len = (size_ < rhs.size_) ? size_ : rhs.size_;
int r = memcmp(data_, rhs.data_, min_len);
// 前缀相同的,长度长的大
if (r == 0) {
if (size_ < rhs.size_)
r = -1;
else if (size_ > rhs.size_)
r = 1;
}
return r;
}
inline bool operator==(const Slice& lhs, const Slice& rhs) {
return (lhs.size() == rhs.size()) &&
(memcmp(lhs.data_, rhs.data_, lhs.size()));
}
inline bool operator!=(const Slice& lhs, const Slice& rhs) {
return !(lhs == rhs);
}