如何检查leveldb是否为空

时间:2013-10-26 10:52:46

标签: leveldb

假设您不知道leveldb数据库中的确切键。

我尝试在键范围内插入3个键并使用GetApproximateSizes,结果始终为零。

那么如何检查leveldb中是否有任何键?

2 个答案:

答案 0 :(得分:1)

我们通过更高级别的API levelUP在NodeJS项目中使用leveldb。使用levelUP API,您可以请求所有密钥流,并设置limit=1以将响应限制为最多一个密钥。如果数据库为空,您将获得一个空流,否则您将获得一个只包含一个项目的流。

var empty = true;
db.createReadStream(db, {
    keys: true,
    values: false,
    limit: 1
}.on('data', function(data) {
    empty = false;
}.on('end', function() {
    console.log('db is ' + (empty ? 'empty' : 'not empty')); 
});

我们在npm模块level-is-empty中使用此技术。

由于您需要使用leveldb本机API的解决方案,因此我研究了levelUP如何实现createReadStream() API。

在levelUP中,createReadStream is implemented using an iterator

在levelDOWN中,创建了本机Iterator实例hereCalling next on it tells you whether the iterator has more data or is finished

我找到了一个如何使用原生leveldb迭代器here

的示例

显然,迭代器方法Valid()告诉您是否有更多的键要读取。因此,通过简单地调用SeekToFirst(),然后调用Valid(),您应该能够找出数据库中是否存在任何键。

这是我最好的猜测(代码未经测试,我手边没有C编译器)

leveldb::Iterator* it = db->NewIterator(leveldb::ReadOptions());
it->SeekToFirst();
bool isEmpty = !(it->Valid());
delete it;

答案 1 :(得分:0)

您不能只使用leveldb扫描并打印所有键和值。例如,要打印数据库中的所有键和值,您可以执行以下操作:

  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 scan
  delete it;

现在GetApproximateSizes给出零值,因为你刚刚插入了3个键,它们仍然在内存中(可记忆)并且还没有到达文件系统。一旦memtable满了(默认为4MB),它就会在0级创建第一个文件。因此,它对更大的数据库和更大的键范围更有用。

在你的情况下,文件系统中唯一存在数据的地方是重做日志,如果你的键是字符串,你可以通过在db目录中调用'strings logfile'(在linux中)来打印字符串来快速检查部分密钥是确认数据进入的快速方法。