Beispiel #1
0
            public void Rehash()
            {
                HashEntry[] oldTable    = table;
                int         oldCapacity = oldTable.Length;

                if (oldCapacity >= MAXIMUM_CAPACITY)
                {
                    return;
                }

                /*
                 * Reclassify nodes in each list to new Map.  Because we are
                 * using power-of-two expansion, the elements from each bin
                 * must either stay at same index, or move with a power of two
                 * offset. We eliminate unnecessary node creation by catching
                 * cases where old nodes can be reused because their next
                 * fields won't change. Statistically, at the default
                 * threshold, only about one-sixth of them need cloning when
                 * a table doubles. The nodes they replace will be garbage
                 * collectable as soon as they are no longer referenced by any
                 * reader thread that may be in the midst of traversing table
                 * right now.
                 */

                HashEntry[] newTable = HashEntry.NewArray(oldCapacity << 1);
                threshold = (int)(newTable.Length * loadFactor);
                int sizeMask = newTable.Length - 1;

                for (int i = 0; i < oldCapacity; i++)
                {
                    // We need to guarantee that any existing reads of old Map can
                    //  proceed. So we cannot yet null out each bin.
                    HashEntry e = oldTable[i];

                    if (e != null)
                    {
                        HashEntry next = e.next;
                        int       idx  = e.hash & sizeMask;

                        //  Single node on list
                        if (next == null)
                        {
                            newTable[idx] = e;
                        }
                        else
                        {
                            // Reuse trailing consecutive sequence at same slot
                            HashEntry lastRun = e;
                            int       lastIdx = idx;
                            for (HashEntry last = next; last != null; last = last.next)
                            {
                                int k = last.hash & sizeMask;
                                if (k != lastIdx)
                                {
                                    lastIdx = k;
                                    lastRun = last;
                                }
                            }
                            newTable[lastIdx] = lastRun;

                            // Clone all remaining nodes
                            for (HashEntry p = e; p != lastRun; p = p.next)
                            {
                                int       k = p.hash & sizeMask;
                                HashEntry n = newTable[k];
                                newTable[k] = new HashEntry(p.key, p.hash, n, p.value);
                            }
                        }
                    }
                }
                table = newTable;
            }
Beispiel #2
0
 public Segment(int initialCapacity, float lf)
 {
     loadFactor = lf;
     SetTable(HashEntry.NewArray(initialCapacity));
 }