2017-11-23 5 views
0

私は、数百万ものレコードを含むことができるファイル(私たちの便宜のためにcsvファイルを言うことができます)を持っています。このファイルには複数の重複が含まれている場合があります。一意のレコードを検索したいが、特定の列のみに基づいていると言うことができます(プライマリ列であると言います)。スケーラブルなソリューションを使用して、Javaの非常に大きなファイルから一意のレコードを見つける方法は?

File ScreenShot このファイルでは、最初の2つのレコードはまったく同じではありません。しかし、私がcolumn1をプライマリと見なすと、最初の2つのレコードは私のために重複しているので(column1に同じ値を持つので)、私は最終結果に1つしか入れません。

私の現在のアプローチでは、キー値がプライマリ列のデータで、対応するマップされた値がレコード全体であるマップを使用しています。 このようにしてすべてのレコードを繰り返し処理し、レコードごとにプライマリ列のデータをキー値として、レコード全体をマップ値としてそれぞれ送ります。この方法では、反復中に重複しているプラ​​イマリ列が見つかるたびに、同じプライマリキーデータ(マップは重複を許可しない)と同じレコードを置き換えます。

このメソッドは正常に動作しますが、ヒープスペースが不足している可能性がある大きなファイルには適用できません。また、時間の複雑さも良くありません。誰かがより良い方法を提案できますか?

+1

SQL、Hadoopなどのジョブに適切なツールを使用してください。 – ronhash

+0

これらのデータはどのDBにも格納されておらず、生ファイルとしてのみ使用できるため、SQLはオプションではありません。 – DockYard

+0

でも、SQLiteはファイルですが、これでクエリを実行できるようになり、nitは* any *のインストールを要求します – ronhash

答えて

1

オフ・ヒープ・データ構造が必要です。ヘーゼルキャストまたはレディスを試してみてください。そうでない場合は、他に何も使用できない場合は、一意のレコードの行番号だけを格納し、2回目に出力を書き込むと、メモリ要件が大幅に減ります。また、物理メモリー上でもヒープ・サイズを増やすことはできますが、スワップするとパフォーマンスが低下する可能性があります。それでも十分でない場合は、独自のオフ・ヒープ・コードを記述する必要があります。 ByteBuffer.allocateDirect()でメモリを割り当ててそこにデータを書き込み、マップを使用してデータにオフセットを格納することができます。

関連する問題