在真正开始研究leveldb的存储过程之前,先来研究一下相关的结构,首先是slice。
为了操作方便,leveldb将数据和长度包装成了slice使用,至于为什么要这么做,估计是两位大神是为了效率的提升,避免一些不必要的操作吧。
class LEVELDB_EXPORT Slice {
public:
//创建一个空slice
Slice() : data_(""), size_(0) { }
// 传入数据指针和长度创建一个slice
Slice(const char* d, size_t n) : data_(d), size_(n) { }
// 传入一个string对象,创建一个slice
Slice(const std::string& s) : data_(s.data()), size_(s.size()) { }
// 传入一个字符串创建slice
Slice(const char* s) : data_(s), size_(strlen(s)) { }
// 定义默认拷贝构造和默认赋值函数
Slice(const Slice&) = default;
Slice& operator=(const Slice&) = default;
// 返回slice数据的指针
const char* data() const { return data_; }
// 返回slice数据的长度
size_t size() const { return size_; }
// 判断数据是否为空
bool empty() const { return size_ == 0; }
// 重载【】
char operator[](size_t n) const {
assert(n < size());
return data_[n];
}
// 清空数据
void clear() { data_ = ""; size_ = 0; }
// slice丢掉前n个字节
void remove_prefix(size_t n) {
assert(n <= size());
data_ += n;
size_ -= n;
}
std::string ToString() const { return std::string(data_, size_); }
// 比较方式. 返回值:
// < 0 iff "*this" < "b",
// == 0 iff "*this" == "b",
// > 0 iff "*this" > "b"
int compare(const Slice& b) const;
// 判断slice是否以“x”开头
bool starts_with(const Slice& x) const {
return ((size_ >= x.size_) &&
(memcmp(data_, x.data_, x.size_) == 0));
}
private:
const char* data_;
size_t size_;
};
inline bool operator==(const Slice& x, const Slice& y) {
return ((x.size() == y.size()) &&
(memcmp(x.data(), y.data(), x.size()) == 0));
}
inline bool operator!=(const Slice& x, const Slice& y) {
return !(x == y);
}
inline int Slice::compare(const Slice& b) const {
const size_t min_len = (size_ < b.size_) ? size_ : b.size_;
int r = memcmp(data_, b.data_, min_len);
if (r == 0) {
if (size_ < b.size_) r = -1;
else if (size_ > b.size_) r = +1;
}
return r;
}
学习是一种慰藉,编程是一种情怀,技术提升永不可辜负!