Ключ LevelDB, значение из CSV - PullRequest
3 голосов
/ 01 февраля 2012

У меня огромная база данных csv-файлов из ~ 5M строк с полями ниже

start_ip,end_ip,country,city,lat,long 

Я храню их в LevelDB, используя start_ip в качестве ключа и остальные в качестве значения.

Какя могу получить записи для ключей, где

( ip_key > start_ip and ip_key < end_ip )

Любое альтернативное решение.

1 Ответ

2 голосов
/ 01 февраля 2012

Я предполагаю, что ваши ключи - это хэш-значения IP, а хэши - это 64-разрядные целые числа без знака, но если это не так, просто измените приведенный ниже код, чтобы учесть правильные ключи.

void MyClass::ReadRecordRange(const uint64 startRange, const uint64 endRange)
{
    // Get the start slice and the end slice
    leveldb::Slice startSlice(static_cast<const char*>(static_cast<const void*>(&startRange)), sizeof(startRange));
    leveldb::Slice endSlice(static_cast<const char*>(static_cast<const void*>(&endRange)), sizeof(endRange));

    // Get a database iterator
    shared_ptr<leveldb::Iterator> dbIter(_database->NewIterator(leveldb::ReadOptions()));

    // Possible optimization suggested by Google engineers 
    // for critical loops. Reduces memory thrash.
    for(dbIter->Seek(startSlice); dbIter->Valid() && _options.comparator->Compare(dbIter->key(), endSlice)<=0); dbIter->Next())
    {
        // get the key
        dbIter->key().data();

        // get the value
        dbIter->value().data();

        // TODO do whatever you need to do with the key/value you read
    }
}

Обратите внимание, что _options - это тот же leveldb::Options, с которым вы открыли экземпляр базы данных. Вы хотите использовать компаратор, указанный в параметрах, чтобы порядок, в котором вы читали записи, соответствовал порядку в базе данных.

Если вы не используете boost или tr1, то вы можете использовать что-то похожее на shared_ptr или просто удалить leveldb::Iterator самостоятельно. Если вы не удалите итератор, вы потеряете память и получите утверждения в режиме отладки.

...