Leveldb中每次都写都是通过Batch的方式进行批量操作,而Batch本质上做的事情就是将多次操作进行了编码,先通过WAL日志将编码后的内容落盘,然后交由Memtable进行批量写入,首先让我们看下Batch的结构。
class LEVELDB_EXPORT WriteBatch {
public:
.....
private:
friend class WriteBatchInternal;
// 核心就是一个string,每次操作都会编码成string放在这里。
std::string rep_; // See comment in write_batch.cc for the format of rep_
};
接着我们看下WriteBatch是如何存放一次操作的。
void WriteBatch::Put(const Slice& key, const Slice& value) {
WriteBatchInternal::SetCount(this, WriteBatchInternal::Count(this) + 1);
rep_.push_back(static_cast<char>(kTypeValue));
// 先通过varint把size写入,接着写内容
PutLengthPrefixedSlice(&rep_, key);
PutLengthPrefixedSlice(&rep_, value);
}
最后我们来看下,一个WriteBatch编码后的内容格式,如下图:
一条数据包含了sequence number、entry number、batch data,前8个字节用来存放sequence nunber,一次WriteBatch会分配一个递增的sequence nunber。接着8个字节用来存放这个WriteBatch中包含了多少次操作,接着就是每一次操作的具体内容了,就是上面提到的写入操作类型、key/value值等。