当前位置: 首页 > 工具软件 > LevelDB > 使用案例 >

[leveldb] 1-leveldb概述

司国源
2023-12-01

google的leveldb是久闻大名的数据存储库,可以说是开源爱好者的必推项目了,最近准备在自己的程序中使用一下leveldb,并读源码,因此想记录一下学习的过程。

leveldb的安装,请参考:http://blog.csdn.net/koko2015c/article/details/68066761,其实也就是make一下然后拷贝动态链接库常规的操作,不过最新的leveldb版本好像已经改用cmake编译了,看来cmake还是有必要掌握一下的吧。

leveldb是单机的K/V数据存储系统,用到了 LSM Tree的设计思想,使用对日志的操作代替对磁盘的随机存取,这种顺序操作避免了随机写所带来的时间负担,不过同时也抛弃了随机查询的速度优势,即:使用顺序读写代替随机读写,虽然顺序写比随即写的速度快,但顺序读比随机读的速度慢!

较新的数据都被append到log中然后放到称为memtable的顺序缓存上,当memtable的体积足够大了以后将变为immemtable,数据移到外存,加入SSTable,这是一个有序的层次结构,用于存放所有的“旧数据”(相对于memtable中的新数据),每个层次存放的key没有重复,以便于新来的数据快速合并(compaction)到SSTable中。

SSTable的层次结构应该就是系统被成为“leveldb”的原因了!

conpaction是SSTable操作的核心操作,因为是对SSTable的内容扩充,所以最坏情况可能会导致对SSTable的数据整体重新写一遍!对SSTable分层以后,leveldb选择将新来的数据做的处理是:所有的操作都是延时的操作。

Code:db/memtable.cc(82-106)


void MemTable::Add(SequenceNumber s, ValueType type,
                   const Slice& key,
                   const Slice& value) {
  //  Format of an entry is concatenation of:
  //  key_size     : varint32 of internal_key.size()
  //  key bytes    : char[internal_key.size()]
  //  value_size   : varint32 of value.size()
  //  value bytes  : char[value.size()]
  size_t key_size = key.size();
  size_t val_size = value.size();
  size_t internal_key_size = key_size + 8;
  const size_t encoded_len =
      VarintLength(internal_key_size) + internal_key_size +
      VarintLength(val_size) + val_size;
  char* buf = arena_.Allocate(encoded_len);
  char* p = EncodeVarint32(buf, internal_key_size);
  memcpy(p, key.data(), key_size);
  p += key_size;
  EncodeFixed64(p, (s << 8) | type);
  p += 8;
  p = EncodeVarint32(p, val_size);
  memcpy(p, value.data(), val_size);
  assert(p + val_size == buf + encoded_len);
  table_.Insert(buf);
}

memtable的添加/删除操作,当type为kTypeDeletion的时候表示删除操作,value没有值。leveldb没有单独的删除操作,删除表现为特别的添加!

实例:Demo

demo.cpp作为leveldb的一个简单应用,创建数据库并读/写数据库

#include "leveldb/db.h"
#include <cassert>
#include <iostream>

using namespace std;
using namespace leveldb;

int main() 
{
    leveldb::DB *db;
    leveldb::Options options;
    options.create_if_missing = true;
    leveldb::Status status = leveldb::DB::Open(options, "testdb", &db);
    assert(status.ok());

    status = db->Put(WriteOptions(), "abc", "levelDB here!");
    assert(status.ok());
    string res;
    status = db->Get(ReadOptions(), "abc", &res);
    assert(status.ok());
    cout << res << endl;

    delete db;
    return 0;
}

最后是使用文档: https://github.com/google/leveldb/blob/master/doc/index.md

 

 类似资料: