表現すると次のようなイメージです。表現すると次のようなイメージです。リハッシュハッシュテーブルの配列の密度が高くなってくると衝突回数が多くなります。一定値以上になれば配列のサイズを増やします。これをリハッシュと呼びます。倍にして全要素を新しい配列にコピーする場合、次のようなイメージです。一度に行うリハッシュのコストを下げる工夫のされたハッシュテーブルです。以上がハッシュテーブルの基礎的な内容です。詳細に知りたい方は次の文献が非常に詳しく解説されていてるのでオススメです。小さなハッシュテーブル(バケット)を束ねたハッシュテーブルであり、リハッシュがバケット単位で行われるので一度のリハッシュにかかるコストが低いのが特徴です。各バケットへのポインタを格納したディレクトリとバケットから成ります。構造は次のように表されます。表現することにします。ハッシュ値からディレクトリのインデックスを決定する際にハッシュ値の上位何ビットを使用するかを意味します。そのバケットがハッシュ値の上位何ビットまで同じキーの要素を格納できるかを意味します。キーの要素の格納先になっています。表現すると次のようなイメージです。定義は雰囲気で感じとってください。次のキーの要素を格納することを考えます。指し示すバケットが格納先のバケットになります。ハッシュテーブルのインデックスになります。表現すると次のようなイメージです。定義は雰囲気で感じとってください。指し示すバケットが満杯であることがわかります。ビットが同じキーの要素を格納できるよう、バケットを分割します。要素も挿入できるようになります。表現すると次のようなイメージです。指し示すバケットが満杯であることがわかります。これ以上バケットを分割することもできません。倍のサイズの配列を生成し、格納しているポインタをコピーします。ディレクトリを拡張するだけではバケットの数は増えません。表現すると次のようなイメージです。格納先のバケットも分割できるようになります。バケットを分割する際、分割対象のバケットのリハッシュしか行われず、ディレクトリを拡張する際もディレクトリのポインタのコピーしか発生しないことがポイントです。バケットでの衝突処理については触れませんでしたが、普通のハッシュテーブル同様、開番地法等による衝突処理が必要なので注意してください。学ぶには良い対象です。次のように定義されています。独自のハッシュ関数のようです。最大値としたものとほぼ同じなので、線形合同法を意識した実装と思われます。どれも同じハッシュ値になるので、これらの文字列を組み合わせることで同じハッシュ値になるキーを大量に作成可能です。0;}上記のコードの実行結果は次のとおりです。次のように定義されています。gdbm_file_header;主要なメンバの意味は次のとおりです。サイズによって異なるマジックナンバーになる。データベースファイルを作成した環境と使用する環境が異なるとマジックナンバーの不一致によりエラーになる場合がある。バケットに格納できる要素数ヘッダの情報から、データベースファイルを作成する環境と使用する環境は統一した方が良いことがわかります。データベースファイルを作成してヘッダ情報を確認してみましょう。0;}各値は次のようになっています。あることがわかります。次のように定義されています。hash_bucket;主要なメンバの意味は次のとおりです。一致するとバケットが満杯であることを意味します。関数ですが、次の箇所でバケットを分割するかどうか判断しています。次のように定義されています。bucket_element;メンバの意味は次のとおりです。キーの比較の際に使うことで、実際の要素にアクセスする回数を減らしている。