3

我有大约 5M 行的巨大 csv 文件数据库,其中包含以下字段

start_ip,end_ip,country,city,lat,long 

我将这些存储在 LevelDB 中,使用 start_ip 作为键,rest 作为值。

如何检索键的记录

( ip_key > start_ip and ip_key < end_ip )

任何替代解决方案。

4

1 回答 1

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,那么您可以使用与 the 类似的其他东西,shared_ptr或者自己删除leveldb::Iterator。如果您不删除迭代器,那么您将泄漏内存并在调试模式下获得断言。

于 2012-02-01T17:39:47.330 回答