2012-02-01 8 views
3

Я огромная базу данных в формате CSV файл строк ~ 5М, имеющей ниже пологоключа LevelDB, значение из CSV

start_ip,end_ip,country,city,lat,long 

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

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

(ip_key > start_ip and ip_key < end_ip) 

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

ответ

2

Я предполагаю, что ваши ключи являются значениями хэша 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 самостоятельно. Если вы не удалите итератор, вы пропустите память и получите подтверждения в режиме отладки.

+0

Я использую привязки leveldb-jni от источника fusesource (https://github.com/fusesource/leveldbjni). Хотя это не проблема для логики. Я использую ipv4/ipv6 байты в ключах и вам нужно найти входной запрос, принадлежащий некоторому диапазону. –

+0

А, ок ... ну, я только знаком с библиотекой C++, поэтому я не уверен, как это сделать на Java, но сейчас я смотрел на исходный код, и кажется, что вам просто нужно получить 'DBIterator', вызывая метод' iterator (...) 'DB. Оттуда я предполагаю, что вы можете использовать ту же логику, что и выше. Если вы просто хотите выяснить, принадлежит ли ключ к некоторому диапазону, используйте «NativeComparator», чтобы проверить, находится ли ключ между данным диапазоном. – Kiril

+0

спасибо. Это наоборот. Я хочу найти диапазон, в который входит вход; и я сохраняю только начало диапазона в качестве ключа. нет перекрывающихся диапазонов, поэтому это должно быть хорошо. –