.Netの共有ソースCLI実装を調べましたが、拡張時にエントリが再ハッシュされているようです。ただし、.GetHashCode()を使用してHashCodeを再計算する必要はありません。
実装を見るexpand()
と、次の手順が実行される方法がわかります。
- 一時的なバケット配列が作成され、現在のサイズの2倍を超える最小の素数にサイズ設定されます。
- 新しいアレイは、古いバケットアレイから再ハッシュすることで移入されます。
。
for (nb = 0; nb < oldhashsize; nb++)
{
bucket oldb = buckets[nb];
if ((oldb.key != null) && (oldb.key != buckets))
{
putEntry(newBuckets, oldb.key, oldb.val, oldb.hash_coll & 0x7FFFFFFF);
}
}
private void putEntry (bucket[] newBuckets, Object key, Object nvalue, int hashcode)
{
BCLDebug.Assert(hashcode >= 0, "hashcode >= 0"); // make sure collision bit (sign bit) wasn't set.
uint seed = (uint) hashcode;
uint incr = (uint)(1 + (((seed >> 5) + 1) % ((uint)newBuckets.Length - 1)));
do
{
int bucketNumber = (int) (seed % (uint)newBuckets.Length);
if ((newBuckets[bucketNumber].key == null) || (newBuckets[bucketNumber].key == buckets))
{
newBuckets[bucketNumber].val = nvalue;
newBuckets[bucketNumber].key = key;
newBuckets[bucketNumber].hash_coll |= hashcode;
return;
}
newBuckets[bucketNumber].hash_coll |= unchecked((int)0x80000000);
seed += incr;
} while (true);
}
}
新しいアレイが構築され、以降の操作で使用されます。
また、Hashtable.Add()に関するMSDNから:
Countがハッシュテーブルの容量よりも少ない場合、このメソッドはO(1)操作です。新しい要素に対応するために容量を増やす必要がある場合、このメソッドはO(n)演算になります。ここで、nはCountです。