【问题标题】:LevelDB key,value from csvLevelDB 键,来自 csv 的值
【发布时间】:2012-02-24 06:15:31
【问题描述】:

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

start_ip,end_ip,country,city,lat,long 

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

如何检索键的记录,其中

( ip_key > start_ip and ip_key < end_ip )

任何替代解决方案。

【问题讨论】:

    标签: ip-geolocation leveldb


    【解决方案1】:

    我假设您的密钥是 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。如果不删除迭代器,则会泄漏内存并在调试模式下获取断言。

    【讨论】:

    • 我正在使用来自 fusesource(github.com/fusesource/leveldbjni) 的 leveldb-jni 绑定。虽然这不是逻辑的问题。我在键中使用 ipv4/ipv6 字节,需要找出输入查询属于某个范围。
    • 啊,好吧...好吧,我只熟悉C++库,所以我不知道如何在Java中做到这一点,但是我刚才看了一下源代码,它似乎您只需要通过调用数据库的iterator(...) 方法来获取DBIterator。从那里开始,我假设您可以使用与上述相同的逻辑。如果您只想确定键是否属于某个范围,则使用NativeComparator 测试键是否在给定范围之间。
    • 谢谢。但它是另一种方式。我想找到输入所属的范围;并且只存储范围的开始作为键。没有重叠的范围,因此应该没问题。
    • 好的,这就回答了你的问题?如我所见,您的数据库具有键 [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] 并且您调用 ReadRecordRange(4, 7) 它将读取键 [4, 5, 6, 7 ]。这就是你想要的行为,对吗?
    • 不,假设我的键是 [1,3,5,7,9],所以对于键 4,我需要获取键 ==3 的记录。键 1 用于范围 1-2 中的所有项目,键 7 相同,映射到范围 7-8 中的所有项目。由于我的所有记录都已经排序并且没有重叠范围,因此它的工作方式如下。我用 dbiterator 寻找,然后检查上一个记录。成功了!
    猜你喜欢
    • 2021-07-02
    • 2014-05-27
    • 2014-03-20
    • 1970-01-01
    • 1970-01-01
    • 2014-02-17
    • 1970-01-01
    • 1970-01-01
    • 2017-09-05
    相关资源
    最近更新 更多