/*LOCKING: _lock must be held*/ void Rehash() { uint newSize = (uint)HashHelpers.GetPrime((data.Length << 1) | 1); //Console.WriteLine ("--- resizing from {0} to {1}", data.Length, newSize); Ephemeron[] tmp = new Ephemeron [newSize]; GC.register_ephemeron_array(tmp); size = 0; for (int i = 0; i < data.Length; ++i) { object key = data[i].key; object value = data[i].value; if (key == null || key == GC.EPHEMERON_TOMBSTONE) { continue; } int len = tmp.Length; int idx, initial_idx; int free_slot = -1; idx = initial_idx = (RuntimeHelpers.GetHashCode(key) & int.MaxValue) % len; do { object k = tmp [idx].key; //keys might be GC'd during Rehash if (k == null || k == GC.EPHEMERON_TOMBSTONE) { free_slot = idx; break; } if (++idx == len) //Wrap around { idx = 0; } } while (idx != initial_idx); tmp [free_slot].key = key; tmp [free_slot].value = value; ++size; } data = tmp; }