2012-02-01 19 views
3

からの値が、私はキーとしてstart_ip使用し、値として休むLevelDBでこれらを格納していますフィールドLevelDBキー、CSV

start_ip,end_ip,country,city,lat,long 

下回った〜5M行の巨大なCSVファイルのデータベースをしました。

にはどうすればいいのキー

(ip_key > start_ip and ip_key < end_ip) 

どれ代替ソリューションのためのレコードを取得することができます。

答えて

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同じであることに注意してください。レコードを読み取る順序がデータベース内の順序と同じになるように、オプションで指定されたコンパレータを使用する必要があります。

ブーストまたはtr1を使用していない場合は、shared_ptrと類似のものを使用するか、自分でleveldb::Iteratorを削除してください。イテレータを削除しないと、メモリがリークしてデバッグモードでアサートされます。

+0

fuseource(https://github.com/fusesource/leveldbjni)のleveldb-jniバインディングを使用しています。それは論理の問題ではありませんが。キーでipv4/ipv6バイトを使用しており、入力クエリがある範囲に属しているかどうかを調べる必要があります。 –

+0

ああ、まあ、私はC++ライブラリに精通しているだけなので、Javaでそれをどうやって行うのかは分かりませんが、ソースコードを見ています。 DBの 'iterator(...)'メソッドを呼び出して 'DBIterator'を呼び出します。そこから、私はあなたが上記と同じロジックを使用できると仮定します。キーがある範囲に属しているかどうかを調べるには、 'NativeComparator'を使用して、キーが指定された範囲内にあるかどうかをテストします。ありがとうございます。 – Kiril

+0

それはもう一方の方法です。私は入力が属する範囲を探したい。範囲の開始のみをキーとして格納しています。重複範囲がないので、これはうまくいくはずです。 –

関連する問題