LSM引擎:MemTable的初步实现

MemTable简介

  1. 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();
}
posted @ 2026-08-26 16:01  lf123z  阅读(3)  评论(0)    收藏  举报