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); } } }
public void UpdateBitmapHeader(int blockIndex, HeapOnNodeBitmapHeader header) { HeapOnNodeBitmapBlockData blockData = (HeapOnNodeBitmapBlockData)GetBlockData(blockIndex); // header is fixed length, so we won't overwrite anything but the old header blockData.BitmapHeader = header; UpdateBuffer(blockIndex, blockData); }
public HeapOnNodeBitmapHeader GetBitmapHeader(int blockIndex) { if (blockIndex % 128 == 8) { HeapOnNodeBitmapBlockData bitmapBlockData = (HeapOnNodeBitmapBlockData)GetBlockData(blockIndex); return(bitmapBlockData.BitmapHeader); } else { throw new Exception("Invalid block index"); } }
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)); }