예제 #1
0
            public object Pop()
            {
                if (countFree == 0)
                {
                    Debug.Assert(false);
                    throw new InvalidOperationException();
                }

                countFree--;
                countInUse++;
                int    i    = countFree & (blockSize - 1);
                object item = currentFreeItemsBlock.Items[i];

                currentFreeItemsBlock.Items[i] = null;
#if DEBUG
                if (!freed.ContainsKey(item))
                {
                    Debug.Assert(false);
                    throw new InvalidOperationException();
                }
                freed.Remove(item);
#endif

                if (i == 0)                                            // this container is now empty
                {
                    sharedEmptyBlocksList.Push(currentFreeItemsBlock); // give back

                    // transfer extra to here (or it's null)
                    currentFreeItemsBlock = extraFreeItemsBlock;
                    extraFreeItemsBlock   = null;

                    if (currentFreeItemsBlock == null)
                    {
                        currentFreeItemsBlock = sharedFreeItemsList.TryPop(); // try to get a new set of free items
                        if (currentFreeItemsBlock != null)
                        {
                            Debug.Assert(currentFreeItemsBlock.BlockSize == blockSize);

                            countFree += blockSize;
#if DEBUG
                            for (int j = 0; j < currentFreeItemsBlock.Items.Length; j++)
                            {
                                freed.Add(currentFreeItemsBlock.Items[j], false);
                            }
                            Debug.Assert(countFree == freed.Count);
#endif
                        }
                    }
                }

                return(item);
            }
예제 #2
0
            public void Push(object item)
            {
#if DEBUG
                if (freed.ContainsKey(item))
                {
                    Debug.Assert(false);
                    throw new ArgumentException();
                }
#endif

                int i = countFree & (blockSize - 1);
                if (i == 0) // full
                {
                    // we're drowning in free objects - push to shared freelist
                    if (extraFreeItemsBlock != null)
                    {
#if DEBUG
                        for (int j = 0; j < extraFreeItemsBlock.Items.Length; j++)
                        {
                            freed.Remove(extraFreeItemsBlock.Items[j]);
                        }
#endif
                        countFree -= blockSize;
                        sharedFreeItemsList.Push(extraFreeItemsBlock);
                        extraFreeItemsBlock = null;
#if DEBUG
                        Debug.Assert(countFree == freed.Count);
#endif
                    }

                    // transfer current free block to extra (or might be null)
                    extraFreeItemsBlock   = currentFreeItemsBlock;
                    currentFreeItemsBlock = null;

                    // create new current container for freed items
                    currentFreeItemsBlock = sharedEmptyBlocksList.TryPop();
                    if (currentFreeItemsBlock == null)
                    {
                        currentFreeItemsBlock = new Block(blockSize);
                    }
                }

                currentFreeItemsBlock.Items[i] = item;
                countFree++;
                countInUse--;
#if DEBUG
                freed.Add(item, false);
                Debug.Assert(countFree == freed.Count);
#endif
            }