LSM引擎:MemTable的初步实现
MemTable简介
- MemTable是LSM Engine内存的主要数据结构,负责管理内存中的多个跳表,其中有一个活跃跳表和多个只读的冻结跳表,此外MemTable还负责从跳表到后续SST文件的转换。
初步实现
MemTable的初步实现就是对跳表做封装,此外暂时先提供互斥锁管理,后续可能做出改变。
- MemTable类通过智能指针管理活跃表和通过链表管理冻结表
class MemTable {
public:
MemTable();
void Put(const std::string &key, const std::string &value);
std::optional<std::string> Get(const std::string &key);
void Remove(const std::string &key);
private:
std::shared_ptr<SkipList> curr_table_;
std::list<std::shared_ptr<SkipList>> frozen_tables_; // 利用链表实现顺序头插入
size_t frozen_bytes_; // 记录冻结表字节数
std::shared_mutex mutex_;
};
- 需要注意的是MemTable的Get依然需要保持空字符串""代表删除标识,std::nullopt代表节点物理不存在的逻辑
std::optional<std::string> MemTable::Get(const std::string &key) {
std::shared_lock<std::shared_mutex> lock(mutex_);
auto curr_result = curr_table_->Get(key);
// 区分nullopt和"",否则可能导致读取BUG,空字符串逻辑交给上层处理
if (curr_result.has_value()) {
return curr_result;
}
// 只有当活跃跳表物理上找不到key才查找冻结跳表,删除记号直接返回
for (auto frozen_table : frozen_tables_) {
auto frozen_result = frozen_table->Get(key);
if (frozen_result.has_value()) {
return frozen_result;
}
}
return std::nullopt;
}
测试
#include <gtest/gtest.h>
#include "../include/memtable/memtable.h"
TEST(MemTable, BasicOperations) {
MemTable mt;
mt.Put("key1", "value1");
EXPECT_EQ("value1", mt.Get("key1"));
mt.Remove("key1");
EXPECT_EQ(mt.Get("key1").value(), "");
}
int main(int argc, char **argv) {
testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
浙公网安备 33010602011771号