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); }
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 }