CeilLog2() static private method

static private CeilLog2 ( int x ) : int
x int
return int
Exemplo n.º 1
0
        internal void Resize(int numArraySlots, int numNodes)
        {
#if DEBUG
            Debug.Assert(!isResizing);
            isResizing = true;
#endif
            Debug.Assert(numArraySlots >= 0 && numNodes >= 0);

            var oldArray      = array;
            int oldArraySlots = oldArray != null ? oldArray.Length : 0;
            array = numArraySlots != 0 ? new CompactValue[numArraySlots] : null;

            var oldNodes = nodes;
            if (numNodes > 0)
            {
                int logNumNodes = Helpers.CeilLog2(numNodes);
                if (logNumNodes > MaxBits)
                {
                    throw new InvalidOperationException("Table overflow");
                }

                numNodes = 1 << logNumNodes;

                nodes = new Node[numNodes];
                for (int i = 0; i < nodes.Length; i++)
                {
                    nodes[i].Next = -1;
                }
            }
            else
            {
                nodes = EmptyNodes;
            }

            lastFreeNode = numNodes;

            //copy from the old array to the new

            int copyArraySlots = oldArraySlots < numArraySlots ? oldArraySlots : numArraySlots;

            if (copyArraySlots != 0)
            {
                Array.Copy(oldArray, array, copyArraySlots);
            }

            //move the remaining elements to the new nodes array

            if (oldArray != null)
            {
                //we know that none of these values will land in the array,
                //so we temporarily null it out in order to prevent InsertNewKey
                //from doing an unnecessary "does it land in the array part" check

                var newArr = array;
                array = null;

                for (int i = copyArraySlots; i < oldArray.Length; i++)
                {
                    var val = oldArray[i];
                    if (val.Val == null)
                    {
                        continue;
                    }

                    var key = new CompactValue(i);
                    var loc = InsertNewKey(key, true);

                    Debug.Assert(loc < 0);
                    nodes[-loc - 1].Value = val;
                }

                array    = newArr;
                oldArray = null;
            }

            //on to the nodes!

            for (int i = oldNodes.Length; i-- != 0;)
            {
                var node = oldNodes[i];
                if (node.Value.Val == null)
                {
                    continue;
                }

                int loc = InsertNewKey(node.Key, true);

                if (loc > 0)
                {
                    array[loc - 1] = node.Value;
                }
                else
                {
                    nodes[-loc - 1].Value = node.Value;
                }
            }

#if DEBUG
            isResizing = false;
#endif
        }
Exemplo n.º 2
0
        private void Grow(CompactValue newKey)
        {
            var arrayHist = new int[MaxBits + 1];

            //count the used slots in the array part

            int numArrayKeys = 0;

            if (array != null)
            {
                for (int lg = 0, ttlg = 1, i = 1; lg <= MaxBits; lg++, ttlg *= 2)
                {
                    int lc  = 0;
                    int lim = ttlg;

                    if (lim > array.Length)
                    {
                        lim = array.Length;
                        if (i > lim)
                        {
                            break;
                        }
                    }

                    for ( ; i <= lim; i++)
                    {
                        if (array[i - 1].Val != null)
                        {
                            lc++;
                        }
                    }

                    arrayHist[lg] += lc;
                    numArrayKeys  += lc;
                }
            }

            //and sum up the rest

            int asIdx;

            int numNodeKeys = 0, numNodeIndexKeys = 0;

            for (int i = 0; i < nodes.Length; i++)
            {
                if (nodes[i].Value.Val == null)
                {
                    continue;
                }

                numNodeKeys++;

                asIdx = ValueToInt(nodes[i].Key);
                if (asIdx > 0 && asIdx <= MaxSize)
                {
                    arrayHist[Helpers.CeilLog2(asIdx)]++;
                    numNodeIndexKeys++;
                }
            }

            //and figure out the sizes

            int totalKeys      = numArrayKeys + numNodeKeys;
            int totalIndexKeys = numArrayKeys + numNodeIndexKeys;

            //including the new key

            totalKeys++;

            asIdx = ValueToInt(newKey);
            if (asIdx > 0 && asIdx <= MaxSize)
            {
                arrayHist[Helpers.CeilLog2(asIdx)]++;
                totalIndexKeys++;
            }

            //moving on...

            int newArrayLen = 0, newArrayKeys = 0;

            for (int i = 0, a = 0, twoToI = 1;
                 twoToI / 2 < totalIndexKeys;
                 i++, twoToI *= 2)
            {
                int hist = arrayHist[i];

                if (hist != 0)
                {
                    a += hist;

                    if (a > twoToI / 2)
                    {
                        newArrayLen  = twoToI;
                        newArrayKeys = a;
                    }
                }

                if (a == totalIndexKeys)
                {
                    //we've counted everything
                    break;
                }
            }

            Debug.Assert(newArrayLen / 2 <= newArrayKeys && newArrayKeys <= newArrayLen);

            //aaaaand, resize!

            Resize(newArrayLen, totalKeys - newArrayKeys);
        }