最新要闻

广告

手机

iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?

iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?

警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案

警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案

家电

LevelDb-用户接口

来源:博客园
目录
  • 优缺点
  • 用户接口
    • 基本读写
      • 打开关闭数据库
      • 读写
      • 原子更新
      • 同步/异步写
    • 并发
    • 迭代器
    • 快照
    • Slice
    • 自定义key比较器
    • 性能相关
      • 压缩
      • 缓存
      • key设计
      • 布隆过滤
    • 获取范围数据大小近似值

优缺点

  • This is not a SQL database. It does not have a relational data model, it does not support SQL queries, and it has no support for indexes.
  • Only a single process (possibly multi-threaded) can access a particular database at a time.
  • There is no client-server support builtin to the library. An application that needs such support will have to wrap their own server around the library.TODO:回头再来理解

用户接口

基本读写

打开关闭数据库

#include #include "leveldb/db.h"leveldb::DB* db;leveldb::Options options;options.create_if_missing = true;leveldb::Status status = leveldb::DB::Open(options, "/tmp/testdb", &db);assert(status.ok());...delete db;

读写

std::string value;leveldb::Status s = db->Get(leveldb::ReadOptions(), key1, &value);if (s.ok()) s = db->Put(leveldb::WriteOptions(), key2, value);if (s.ok()) s = db->Delete(leveldb::WriteOptions(), key1);

原子更新

#include "leveldb/write_batch.h"...std::string value;leveldb::Status s = db->Get(leveldb::ReadOptions(), key1, &value);if (s.ok()) {  leveldb::WriteBatch batch;  batch.Delete(key1);  batch.Put(key2, value);  s = db->Write(leveldb::WriteOptions(), &batch);}

delete key1和put key2在一个原子请求中,要么都不执行,要么都执行。

同步/异步写

leveldb::WriteOptions write_options;write_options.sync = true;db->Put(write_options, ...);

默认写是异步的,可以设置上述参数实现同步写。异步写速度快。

并发

一个数据库同时只能被一个进程使用。一个进程中的DB对象是线程安全的,但是Iterator和WriteBatch这些对象不是。


(资料图)

迭代器

leveldb::Iterator* it = db->NewIterator(leveldb::ReadOptions());for (it->SeekToFirst(); it->Valid(); it->Next()) {  cout << it->key().ToString() << ": "  << it->value().ToString() << endl;}assert(it->status().ok());  // Check for any errors found during the scandelete it;

遍历所有的数据。

for (it->Seek(start);   it->Valid() && it->key().ToString() < limit;   it->Next()) {  ...}

遍历[start, limit)区间的数据。

for (it->SeekToLast(); it->Valid(); it->Prev()) {  ...}

倒序遍历,效率不如正序遍历。

快照

leveldb::ReadOptions read_options;    read_options.snapshot = db->GetSnapshot();    assert(status.ok());    status = db->Put(leveldb::WriteOptions(), "key1", "value2");    leveldb::Iterator* it = db->NewIterator(read_options);    for (it->SeekToFirst(); it->Valid(); it->Next()) {        std::cout << it->key().ToString() << ": "  << it->value().ToString() << std::endl;    }

创建一个数据状态的可读快照。如上所示,Put key1,value2之前,数据库里key1对应的是value1,在Put之前创建了快照对象,Put之后,用快照的key1的值依然是value1。

Slice

it->key() and it->value()返回的都是Slice实例,能和string互转。

leveldb::Slice s1 = "hello";std::string str("world");leveldb::Slice s2 = str;

自定义key比较器

默认的是按key的字典序进行排序。

class TwoPartComparator : public leveldb::Comparator { public:  // Three-way comparison function:  //   if a < b: negative result  //   if a > b: positive result  //   else: zero result  int Compare(const leveldb::Slice& a, const leveldb::Slice& b) const {    int a1, a2, b1, b2;    ParseKey(a, &a1, &a2);    ParseKey(b, &b1, &b2);    if (a1 < b1) return -1;    if (a1 > b1) return +1;    if (a2 < b2) return -1;    if (a2 > b2) return +1;    return 0;  }  // Ignore the following methods for now:  const char* Name() const { return "TwoPartComparator"; }  void FindShortestSeparator(std::string*, const leveldb::Slice&) const {}  void FindShortSuccessor(std::string*) const {}};TwoPartComparator cmp;leveldb::DB* db;leveldb::Options options;options.create_if_missing = true;options.comparator = &cmp;leveldb::Status status = leveldb::DB::Open(options, "/tmp/testdb", &db);...

性能相关

压缩

leveldb::Options options;options.compression = leveldb::kNoCompression;... leveldb::DB::Open(options, name, ...) ....

默认开启压缩,可用如上代码关闭。

缓存

#include "leveldb/cache.h"leveldb::Options options;options.block_cache = leveldb::NewLRUCache(100 * 1048576);  // 100MB cacheleveldb::DB* db;leveldb::DB::Open(options, name, &db);... use the db ...delete dbdelete options.block_cache;

设置缓存。

leveldb::ReadOptions options;options.fill_cache = false;leveldb::Iterator* it = db->NewIterator(options);for (it->SeekToFirst(); it->Valid(); it->Next()) {  ...}

大量读请求的场景下,可以关闭文件缓存,防止在内存中缓存大量数据。

key设计

leveldb中连续的key会存在一起,根据这个特性,经常一起访问的数据key最好相似。

filename -> permission-bits, length, list of file_block_idsfile_block_id -> data

比如有这两类数据,filename最好以"/"开始,file_block_id最好以数据开始,这样查找filename对应的元信息时,不会扫描到file_block_id对应的数据。

布隆过滤

leveldb::Options options;options.filter_policy = NewBloomFilterPolicy(10);leveldb::DB* db;leveldb::DB::Open(options, "/tmp/testdb", &db);... use the database ...delete db;delete options.filter_policy;

设置布隆过滤器,取key的特征,判定key存在的概率,从而减少不必要读。

获取范围数据大小近似值

leveldb::Range ranges[2];ranges[0] = leveldb::Range("a", "c");ranges[1] = leveldb::Range("x", "z");uint64_t sizes[2];db->GetApproximateSizes(ranges, 2, sizes);

参考资料:levedb doc

关键词: