HAMTの詳細について頭を悩ませようとしています。理解するためだけに、Javaで自分で実装したでしょう。私は Tries に精通しており、HAMT の主なコンセプトを理解していると思います。
基本的、
2 種類のノード:
キー/値
Key Value Node:
K key
V value
索引
Index Node:
int bitmap (32 bits)
Node[] table (max length of 32)
- オブジェクトの 32 ビット ハッシュを生成します。
- 一度に 5 ビットずつハッシュをステップスルーします。
(0-4, 5-9, 10-14, 15-19, 20-24, 25-29, 30-31)
注: 最後のステップ (7 番目) は 2 ビットのみです。 - 各ステップで、ビットマップ内のその 5 ビット整数の位置を見つけます。例えば
integer==5 bitmap==00001
- ビットが 1 の場合、ハッシュのその部分が存在します。
- ビットが 0 の場合、キーは存在しません。
- キーが存在する場合は、ビットマップ内の 0 から位置までの 1 の数を数えて、テーブルのインデックスを見つけます。例えば
integer==6 bitmap==0101010101 index==3
- テーブルがキー/値ノードを指している場合は、キーを比較します。
- テーブルがインデックス ノードを指している場合は、1 ステップ先の 2 に進みます。
私がよく理解していない部分は、衝突の検出と軽減です。リンクされた論文で、彼はそれをほのめかしています:
次に、既存のキーが新しいサブハッシュ テーブルに挿入され、新しいキーが追加されます。ハッシュの 5 ビットが使用されるたびに、衝突の確率は 1/32 に減少します。32 ビット ハッシュ全体が消費される場合があり、2 つのキーを区別するために新しいハッシュを計算する必要があります。
「新しい」ハッシュを計算し、その新しいハッシュにオブジェクトを格納するとします。構造内のオブジェクトをどのように検索できますか? ルックアップを行うとき、「再計算されたハッシュ」ではなく「初期」ハッシュを生成しませんか。
私は何かが欠けているに違いない.....
ところで: HAMT はかなりうまく機能します。私のテストでは、ハッシュ マップとツリー マップの間に位置しています。
Data Structure Add time Remove time Sorted add time Sorted remove time Lookup time Size
Java's Hash Map 38.67 ms 18 ms 30 ms 15 ms 16.33 ms 8.19 MB
HAMT 68.67 ms 30 ms 57.33 ms 35.33 ms 33 ms 10.18 MB
Java's Tree Map 86.33 ms 78 ms 75 ms 39.33 ms 76 ms 8.79 MB
Java's Skip List Map 111.33 ms 106 ms 72 ms 41 ms 72.33 ms 9.19 MB