4

leveldbを使用してキープレフィックスで反復するキー列挙子を実装する効率的な方法を探しています。キーはバイト配列であり(dbはデフォルトのバイト配列比較子を使用するため、特定のプレフィックスを持つすべてのキーが順番に格納/取得されます)、イテレーターがキープレフィックスを取得し、それを持つキーを持つデータのみを返すことができるようにしたいと思いますプレフィックス。

デフォルトのdbイテレータを使用または継承し、範囲内の最初のキーを探し(もちろん、それが何であるかを知る必要があります)、プレフィックスで始まるすべてのスライスを検証して返す必要がありますか(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 wrapperにプレフィックス イテレータがあります。メソッド
によって返される範囲で使用されます。startsWith

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