TL;DR
ハッシュテーブルでキーが衝突したとき、配列の別のスロットを順に探査(probing)して解決する方法。クローズドハッシュ法とも呼ぶ。すべてのレコードを 1 つの配列に持つ。
仕組み
Wikipedia によると、衝突したキーは、見つかるか空のスロットに当たるまで、他のスロットを探して格納・検索する。探査の順番には次の 3 つがある。
- 線形探査: 一定の間隔(多くは 1)で探す
- 二次探査: 間隔を線形に増やすので、位置は二次関数になる
- ダブルハッシュ: 間隔をレコードごとに別のハッシュ関数で決める
線形探査はキャッシュ性能が最もよいが、レコードが固まるクラスタリングに最も弱い。ダブルハッシュはクラスタリングがほとんど起きないが、キャッシュの効きが悪い。二次探査はその中間である。
例
Swiss Table の実装に Deep Dive ! によると、Swiss Table はチェイン法ではなくオープンアドレス法で実装されたハッシュテーブルである。Go1.24で進化したmap型について理解する によると、Go 1.24 から map の内部実装が Swiss Table に変わり、二次探査を組み合わせてクラスタリングを抑えている。
注意点
性能は負荷率(埋まっているスロットの割合)に大きく左右される。良いハッシュ関数でも負荷率はふつう 80% までに抑え、50% 程度が多い。チェイン法は 100% 近くまで使える。
削除にも工夫が要る。削除済みの印を付けるのは簡単だが、いずれテーブルを作り直す必要がある。