hashの実装について

Beautiful Codeという本にhashの実装についての章があったので、少し調べてみた。

参考にしたソース、資料

本ではPythonのhash実装を説明していたが、そこでポイントされていたのが下記の資料。

  • 資料

http://svn.python.org/view/python/trunk/Objects/dictnotes.txt?view=markup

  • ソース

http://svn.python.org/view/python/trunk/Objects/dictobject.c?view=markup

小技

hashのindexを取得する時、配列のサイズで剰余演算を行うが、配列のサイズを2の階乗にしておくと、ビット演算で高速に剰余を取得できる。
上記のdictobject.cの lookdict_string メソッド内で、

i = hash & mask

のような感じの箇所。maskはあらかじめ 配列のサイズ - 1 に設定されている。

open addressでのアドレス取得

ソースの先頭付近のコメントで解説されている。
上と同じlookdict_string メソッド内で、変動値を入れながら、

nextIndex = (currentIndex * 定数値 + ループごとの変動値 + 1) mod entrySize

のようなロジックで次のインデックスを取得している。
ループごとの変動値の初期化にもhash値を使っている所も工夫されている。
コメント部分にも書いてあるが、

 j = ((5*j) + 1) mod 2**i

を繰り返すと、jが重複せずindexを一巡する。