Esempio n. 1
0
        /*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;
        }