4

我正在寻找一种有效的方法来实现使用 leveldb 通过键前缀迭代的键枚举器。键是字节数组(数据库使用默认字节数组比较器,因此具有特定前缀的所有键都按顺序存储/检索),我希望我的迭代器能够采用键前缀并仅返回具有键的数据字首。

我是否必须使用或继承默认的数据库迭代器,寻找范围内的第一个键(当然我需要知道它是什么),然后验证并返回以前缀开头的每个切片(通过覆盖 movenext 或其他东西)? 还是有更有效的方法来实现这一点?

让我知道是否有人已经解决了这个问题并且可以分享代码或总体思路。我正在从 C++/CLI 尝试这个,但任何语言的实现都会有所帮助。

谢谢。-raj。

4

2 回答 2

3

比较器用于确定键是否不同,因此重载它无济于事,因为当您扫描数据库时 - 您必须能够比较完整的键(而不仅仅是前缀)。不需要重载迭代器:键在 leveldb 中排序,您会知道如果遇到具有不同前缀的键,它已经超出范围。你可以像往常一样使用迭代器,只要你的键被正确评估,你应该得到正确的结果:

void ScanRecordRange(const leveldb::Slice& startSlice, const leveldb::Slice& endSlice)
{
    // 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())
    {                
        // Read the record
        if( !dbIter->value().empty() )
        {
            leveldb::Slice keySlice(dbIter->key());
            leveldb::Slice dataSlice(dbIter->data());
            // TODO: process the key/data

        }
    }
}
于 2012-05-08T19:50:41.780 回答
0

我的LevelDB 包装器中有一个前缀迭代器。
在方法返回的范围内使用startsWith

int count = 0;
for (auto& en: ldb.startsWith (std::string ("prefix"))) {++count;}
于 2013-03-26T22:39:05.293 回答