LevelDB 提供三个和写操作相关的接口:
Put 和 Delete 都是直接调用 Write 来实现的:
leveldb::DBImpl::Write 的函数声明如下:
virtual Status Write(const WriteOptions& options, WriteBatch* updates) = 0;
sync
表示是否每次写完都要将日志 flush 到外存。具体代码是 leveldb::DBImpl::Write。
struct DBImpl::Writer {
explicit Writer(port::Mutex* mu)
: batch(nullptr), sync(false), done(false), cv(mu) {}
Status status; // 执行结果
WriteBatch* batch; // 更新的数据(1~多个 key-value)
bool sync; // 是否 flush,WriteOptions.sync
bool done; // 是否已经执行
port::CondVar cv; // 并发控制的条件变量
};
MakeRoomForWrite
以上,便是 LevelDB 的写入流程。写入队列 + 合并写操作,逻辑和代码都十分简洁。比较不足的是,整个写入过程都是单线程的。