ハッシュテーブルは移動する方法です。 検索、挿入、削除のためのO(1)の複雑さが平均化されています。 彼らは木よりも多くのメモリを占有する傾向がありますが、はるかに高速です。
32ビット整数(もちろんIPを32ビット整数に変換することができます)は驚くほど単純で高速です。
ソートされた配列を使用できます。挿入と削除のコストはO(n)ですが、検索はO(log n)です。特にメモリは各ipに対してちょうど4バイトです。 実装は非常に簡単です。恐らく多すぎます。D
バイナリツリーは、検索、挿入、削除のためにO(log n)の複雑さを持ちます。 単純なバイナリツリーでは十分ではありませんが、AVLツリーまたはレッドブラックツリーが必要です。これは実装するのが面倒で複雑な場合があります。AVLツリーとRBTツリーはバランスを取ることができます。不均衡なツリーは、ルックアップのためにO(n)の最悪の時間複雑さを持つため、単純なリンクリストと同じです!
単一でユニークなipの代わりにipの範囲を禁止する必要がある場合は、恐らくRadix Treeと呼ばれるPatricia Trieが必要です。それらは単語辞書とIP辞書用に発明されました。 しかし、うまく書かれていないと、これらの木は遅くなります。 ハッシュテーブルは、簡単なルックアップの方が常に優れています。彼らは本当であるには余りにも速いです:)
今すぐ同期について:
は、アプリケーションの起動時に一度だけのブラックリストを満たしている場合は、あなただけのハッシュテーブル(または基数ツリーを)読んで、プレーンを使用することができますドン」というマルチスレッドとロックに関する問題があります。
非常に頻繁に更新する必要がある場合は、リーダーライターのロックを使用することをお勧めします。
非常に頻繁な更新が必要な場合は、並行ハッシュテーブルを使用することをお勧めします。 警告:あなた自身では書いていない、非常に複雑でバグが多い、Web上の実装を見つける! 彼らは、新しいプロセッサの(比較的に)新しい原子CAS操作をたくさん使用します(CASはCompare and Swapを意味します)。これらは、メモリ上の32ビットまたは64ビットのフィールドを、ロックを必要とせずに単一のアトミック操作で比較およびスワップできる特別な命令セットまたは命令シーケンスです。 それらを使用することは、プロセッサ、運用システム、コンパイラ、アルゴリズムそのものをよく知っていなければならないので、複雑になる可能性があります。 CASの詳細については、http://en.wikipedia.org/wiki/Compare-and-swapを参照してください。
同時AVL木が発明され、私は本当にこれら:)例えば、http://hal.inria.fr/docs/00/07/39/31/PDF/RR-2761.pdf
は、私はちょうど同時基数木が存在することがわかっについて言いたいことがわからないほど複雑であるた: ftp://82.96.64.7/pub/linux/kernel/people/npiggin/patches/lockless/2.6.16-rc5/radix-intro.pdfそれあまりにも複雑です。
並行ソート配列は存在しません。もちろん、更新のためにリーダライタロックが必要です。
非並行ハッシュテーブルを処理するために必要なメモリ量は、ごくわずかです。各IPに対して、IPとポインタに4バイト必要です。 また、格納するアイテムの数よりも大きな素数でなければならない大きな配列のポインタ(またはいくつかのトリックで32ビットの整数)が必要です。 ハッシュテーブルはもちろん、必要に応じて必要に応じてサイズを変更することもできますが、その素数よりも多くの項目を保存することができますが、検索時間はそれほど長くなりません。
ツリーとハッシュテーブルの両方について、空間の複雑さは線形です。
私はこれがマルチスレッドアプリケーションであり、マルチプロセスアプリケーション(fork)ではないことを望みます。 マルチスレッドでない場合は、メモリの一部を高速で信頼できる方法で共有することはできません。
より具体的になると、大きな助けになります。パフォーマンスが重要なシナリオをいくつか説明します。それが完全に異なる実装をとるだろう。 「散在した」単一のIPをターゲットにしている場合と比べて、全体のIP範囲をターゲットにしています。 – Jon
jonのヒントありがとう、私はさらに指定しました! – bratao
メモリ使用量が一定の場合は、ブラックリストに入れることができるIPの最大数に制約があります。 –