Example #1
0
        private HeapOnNodeBlockData GetBlockDataUnbuffered(int blockIndex)
        {
            DataBlock block = DataTree.GetDataBlock(blockIndex);

            if (blockIndex == 0)
            {
                HeapOnNodeFirstBlockData heapFirstBlock = new HeapOnNodeFirstBlockData(block.Data);
                return(heapFirstBlock);
            }
            else
            {
                // HNBITMAPHDR appears at data block 8 (zero-based) and thereafter every 128 blocks.
                // (that is, data block 8, data block 136, data block 264, and so on).
                if (blockIndex % 128 == 8)
                {
                    HeapOnNodeBitmapBlockData bitmapBlock = new HeapOnNodeBitmapBlockData(block.Data);
                    return(bitmapBlock);
                }
                else
                {
                    HeapOnNodePageBlockData pageBlock = new HeapOnNodePageBlockData(block.Data);
                    return(pageBlock);
                }
            }
        }
Example #2
0
        public HeapID AddItemToHeap(byte[] itemBytes)
        {
            if (itemBytes.Length > MaximumAllocationLength)
            {
                throw new ArgumentException("Maximum size of a heap allocation is 3580 bytes");
            }

            if (itemBytes.Length == 0)
            {
                return(HeapID.EmptyHeapID);
            }

            // We can use the Header / BitmapHeader to locate available space,
            // but the final authority is HNPAGEMAP located at the end of each block
            // Note: we are only required to maintain HNPAGEMAP
            for (int blockIndex = 0; blockIndex < m_dataTree.DataBlockCount; blockIndex++)
            {
                HeapOnNodeBlockData blockData = GetBlockData(blockIndex);
                // We need space for the item itself and for a place for it in the page map (2 bytes)
                // We also have to make sure we do not allocate more items then can be represented by hidIndex
                if (blockData.AvailableSpace > itemBytes.Length + 2 && blockData.HeapItems.Count < HeapID.MaximumHidIndex)
                {
                    blockData.HeapItems.Add(itemBytes);
                    UpdateBuffer(blockIndex, blockData);

                    // hidIndex is one-based
                    ushort hidIndex = (ushort)(blockData.HeapItems.Count);
                    return(new HeapID((ushort)blockIndex, hidIndex));
                }
            }

            // no space found in existing blocks, we need to allocate new data block
            int newBlockIndex = m_dataTree.DataBlockCount;
            HeapOnNodeBlockData newBlockData;

            if (newBlockIndex % 128 == 8)
            {
                newBlockData = new HeapOnNodeBitmapBlockData();
            }
            else
            {
                newBlockData = new HeapOnNodePageBlockData();
            }
            newBlockData.HeapItems.Add(itemBytes);
            this.DataTree.AddDataBlock(newBlockData.GetBytes());
            // hidIndex is one-based
            return(new HeapID((ushort)newBlockIndex, 1));
        }