【发布时间】: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 )
任何替代解决方案。
【问题讨论】:
我有大约 500 万行的巨大 csv 文件数据库,其中包含以下字段
start_ip,end_ip,country,city,lat,long
我将这些存储在 LevelDB 中,使用 start_ip 作为键,rest 作为值。
如何检索键的记录,其中
( ip_key > start_ip and ip_key < end_ip )
任何替代解决方案。
【问题讨论】:
我假设您的密钥是 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。如果不删除迭代器,则会泄漏内存并在调试模式下获取断言。
【讨论】:
iterator(...) 方法来获取DBIterator。从那里开始,我假设您可以使用与上述相同的逻辑。如果您只想确定键是否属于某个范围,则使用NativeComparator 测试键是否在给定范围之间。
ReadRecordRange(4, 7) 它将读取键 [4, 5, 6, 7 ]。这就是你想要的行为,对吗?