Предположим, вы не знаете точных ключей в базе данных leveldb.
Я попытался вставить 3 ключа и использовать GetApproximateSizes для диапазона ключей, результат неизменно равен нулю.
Так как же проверить, есть ли ключи в leveldb?
Предположим, вы не знаете точных ключей в базе данных leveldb.
Я попытался вставить 3 ключа и использовать GetApproximateSizes для диапазона ключей, результат неизменно равен нулю.
Так как же проверить, есть ли ключи в leveldb?
Разве вы не можете просто использовать сканирование 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) и еще не достигли файловой системы. Когда таблица памяти заполнена (по умолчанию 4 МБ), она создает первый файл на уровне 0. Поэтому она более полезна для большей базы данных и большего диапазона ключей.
В вашем случае единственным местом в файловой системе, в котором присутствуют данные, будет журнал повторов, и если ваши ключи являются строками, вы можете выполнить быструю проверку, вызвав «strings logfile» (в linux) в каталоге db, чтобы распечатать часть строки вашего keys как быстрый способ подтвердить, что данные вошли.
Мы используем leveldb в проекте NodeJS через высокоуровневый API levelUP. Используя API levelUP, вы можете запросить поток всех ключей и установить 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.
Поскольку вам нужно решение, использующее собственный API leveldb, я изучил, как levelUP реализует createReadStream()
API.
В levelUP createReadStream реализуется с помощью итератора.
В levelDOWN собственный экземпляр Iterator создается здесь. Вызов next
сообщает вам, есть ли у итератора больше данных или он завершен а>.
Я нашел пример использования встроенных итераторов leveldb здесь
По-видимому, метод итератора Valid()
сообщает вам, есть ли еще ключи для чтения. Таким образом, просто вызвав SeekToFirst(), а затем Valid(), вы сможете узнать, есть ли вообще какой-либо ключ в базе данных.
Вот мое лучшее предположение (код не проверен, у меня нет под рукой компилятора C)
leveldb::Iterator* it = db->NewIterator(leveldb::ReadOptions());
it->SeekToFirst();
bool isEmpty = !(it->Valid());
delete it;