2013-10-26 3 views
0

Предположим, что вы не знаете точных ключей в базе данных leveldb.Как проверить, является ли leveldb пустым

Я попытался вставить 3 ключа и использовать GetApproximateSizes в диапазоне клавиш, результат будет равен нулю.

Итак, как вы можете проверить, есть ли какие-либо ключи в leveldb?

ответ

0

Не можете ли вы просто использовать scandb scan и распечатать все ключи и значения. Например, чтобы напечатать все ключи и значения в базе данных вы можете сделать следующее:

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. Таким образом, он более полезен для большей базы данных и большего диапазона ключей.

В вашем случае единственное место в файловой системе, в котором находятся данные, было бы журналом повтора, и если ваши клавиши являются строками, вы можете выполнить быструю проверку, вызвав «файл строк» ​​(в linux) в каталоге db, чтобы распечатать strings часть ваших ключей как быстрый способ подтвердить, что данные вошли.

+0

Конечно, я не перебрать все ключи просто чтобы увидеть, если база данных пуста , Я просто попытался сначала проверить, действительно ли итератор https://github.com/nurettin/pwned/blob/master/leveldb/leveldb.hpp#L153, ​​но все же вы дали мне правильную идею. – nurettin

0

Мы используем leveldb в проекте NodeJS через API более высокого уровня levelUP. Используя API уровня level, вы можете запросить поток всех ключей и установить 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 реализует API createReadStream().

В уровнеUP, createReadStream is implemented using an iterator.

В levelDOWN создается собственный экземпляр Iterator here. Calling 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; 
+0

Что это такое? createReadStream? Я не нашел его в sourcesdb-источниках. – nurettin

+0

Извините, это API-интерфейс [npm module levelup] (https://www.npmjs.com/package/levelup), который находится поверх привязок Nodejs-leveldb, называемых [leveldown] (https: // github. ком/уровень/leveldown /). Я ошибочно предположил, что вы используете NodeJS. Теперь я понимаю, что вы говорите о собственном API-интерфейсе leveldb. Я отредактирую свой ответ. – regular

+0

Ха-ха, просто увидел ваш комментарий к принятому ответу, поэтому вы придумали то же самое решение. – regular

Смежные вопросы