前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >LevelDB Put如何写入数据

LevelDB Put如何写入数据

作者头像
用户4700054
发布2022-08-17 11:33:30
6890
发布2022-08-17 11:33:30
举报

LevelDB Put如何写入数据

leveldb插入数据步骤

  • 用户输入的kv数据首先组装为wal log entry写入到wal log中
  • 然后将kv数据从内存中的wal log entry解析为memtable中的数据
  • 最后在插入到memtable中,完成此次数据的put操作

写入流程分析

  • DB::Put分析
代码语言:javascript
复制
Status DB::Put(const WriteOptions& opt, const Slice& key, const Slice& value) {
  WriteBatch batch;
  // 拼接key和value
  batch.Put(key, value);
  // 写入wal日志和memtable
  return Write(opt, &batch);
}
  • WriteBatch::Put 分析
代码语言:javascript
复制
void WriteBatch::Put(const Slice& key, const Slice& value) {
  WriteBatchInternal::SetCount(this, WriteBatchInternal::Count(this) + 1);
  // 写入value类型,标记为非删除
  rep_.push_back(static_cast<char>(kTypeValue));
  // 组装写入的key和value
  // 按照32位来编码key的大小和key的内存
  PutLengthPrefixedSlice(&rep_, key);
  // 按照32位来编码value的大小和value内容
  PutLengthPrefixedSlice(&rep_, value);
  // 组织后的格式为:|value_type|key_size|key||value_size|value|
}
  • DBImpl::Write 分析
代码语言:javascript
复制
Status DBImpl::Write(const WriteOptions& options, WriteBatch* updates) {
		// 这里是组装wal log格式写入到Wal日志
		// 每个wal log entry格式为: |checksum|record length|record type|data|
      status = log_->AddRecord(WriteBatchInternal::Contents(write_batch));
if (status.ok()) {
			// 这里是把此次write_batch内容插入到memtable中
			// 解析write_batch中的key和value,插入到当前memtable中
        status = WriteBatchInternal::InsertInto(write_batch, mem_);
      }
}

leveldb写入流程调试

  • leveldb 下载
代码语言:javascript
复制
git clone --recurse-submodules https://github.com/google/leveldb.git
mkdir -p build && cd build
// cmake -DCMAKE_BUILD_TYPE=Release .. && cmake --build .
cmake -DCMAKE_BUILD_TYPE=Debug .. && cmake --build .
  • 客户端程序
代码语言:javascript
复制
#include <iostream>
#include <cassert>
#include <leveldb/db.h>
#include <leveldb/write_batch.h>

int main()
{
    // Open a database.
    leveldb::DB* db;
    leveldb::Options opts;
    opts.create_if_missing = true;
    leveldb::Status status = leveldb::DB::Open(opts, "./testdb", &db);
    assert(status.ok());
    
    // Write data.
    status = db->Put(leveldb::WriteOptions(), "name", "jinhelin");
    assert(status.ok());


    // Batch atomic write.
    leveldb::WriteBatch batch;
    batch.Delete("name");
    batch.Put("name0", "jinhelin0");
    batch.Put("name1", "jinhelin1");
    status = db->Write(leveldb::WriteOptions(), &batch);
    assert(status.ok());

    // Scan database.
    leveldb::Iterator* it = db->NewIterator(leveldb::ReadOptions());
    for (it->SeekToFirst(); it->Valid(); it->Next()) {
        std::cout << it->key().ToString() << ": " << 
          it->value().ToString() << std::endl;
    }
    assert(it->status().ok());
    
    // Range scan, example: [name3, name8)
    for (it->Seek("name3"); 
         it->Valid() && it->key().ToString() < "name8"; 
         it->Next()) {
        std::cout << it->key().ToString() << ": " << 
          it->value().ToString() << std::endl;
    } 

}

  • 编译客户端和调试
代码语言:javascript
复制
g++ -ggdb3 -O0 example.cc  -o test -lleveldb -lpthread
gdb ./test
(gdb) info break
Num     Type           Disp Enb Address            What
1       breakpoint     keep y   0x000000000040a756 in leveldb::DB::Open(leveldb::Options const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, leveldb::DB**) at /root/debug/leveldb/db/db_impl.cc:1484
        breakpoint already hit 1 time
2       breakpoint     keep y   0x0000000000409344 in leveldb::DBImpl::Put(leveldb::WriteOptions const&, leveldb::Slice const&, leveldb::Slice const&) 
                                                   at /root/debug/leveldb/db/db_impl.cc:1193
3       breakpoint     keep y   0x00000000004047e9 in leveldb::DBImpl::NewDB() at /root/debug/leveldb/db/db_impl.cc:182
4       breakpoint     keep y   0x00000000004041af in leveldb::DBImpl::DBImpl(leveldb::Options const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) at /root/debug/leveldb/db/db_impl.cc:150
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-04-11,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 存储内核技术交流 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • LevelDB Put如何写入数据
    • leveldb插入数据步骤
      • 写入流程分析
        • leveldb写入流程调试
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档