Beispiel #1
0
        public static short AddVariableSizeItem(IPage page, byte[] itemContent)
        {
            ushort freeSpace  = GetFreeSpace(page);
            var    itemLength = itemContent.Length;

            if (freeSpace < itemLength)
            {
                return(-1);
            }

            short headerLength = BitConverter.ToInt16(page.Content, OnPageOffsets.HeaderLength);

            var lengthMarkers = ReadMarkers(page, headerLength);

            int offset = 0;

            for (short i = 0; i < lengthMarkers.Length; i++)
            {
                offset += Math.Abs(lengthMarkers[i]);
                if (lengthMarkers[i] <= 0)
                {
                    // we have an empty slot
                    if (itemLength == -lengthMarkers[i])
                    {
                        // simple case: a new item has exactly the same size as deleted one, rewrite it
                        RewriteVariableSizeItem(page, itemContent, headerLength, i, offset, freeSpace);
                    }
                    else
                    {
                        PlaceItemToSlot(page, headerLength, itemContent, lengthMarkers, i);
                    }

                    return(i);
                }
            }

            // here we need two extra bytes
            if (freeSpace < itemLength + OnPagePointerSize)
            {
                return(-1);
            }


            // write length of the marker array
            var markersLengthBytes = BitConverter.GetBytes((short)(lengthMarkers.Length + 1));

            markersLengthBytes.CopyTo(page.Content, headerLength);

            // write new length marker
            var newMarkerBytes = BitConverter.GetBytes((short)itemContent.Length);

            newMarkerBytes.CopyTo(page.Content, headerLength + OnPagePointerSize * (lengthMarkers.Length + 1));

            // write item itself
            Buffer.BlockCopy(itemContent, 0, page.Content, page.Content.Length - offset - itemLength, itemLength);

            // write free space
            RadixTreeNodesPageHeader.WriteFreeSpace(page, (ushort)(freeSpace - itemLength - OnPagePointerSize));

            return((short)lengthMarkers.Length);
        }
Beispiel #2
0
 private static void WriteFreeSpace(IPage page, ushort freeSpace)
 {
     RadixTreeNodesPageHeader.WriteFreeSpace(page, freeSpace);
 }