public static void FormatVariableSizeItemsPage(IPage page, PageHeaderBase header, List <byte[]> items) { header.WriteToPage(page); short itemsLength = items.Aggregate <byte[], short>(0, (current, item) => (short)(current + (short)(item.Length))); int remainingSpace = page.Length - // full page length header.Length - // subtract header length itemsLength - // subtract items length items.Count * OnPagePointerSize + OnPagePointerSize; // subtract markers array and its length if (remainingSpace < 0) { throw new ArgumentException("Page have no space to add specified items", nameof(items)); } var content = page.Content; int contentLength = page.Length; int cnt = items.Count; int headerLength = header.Length; short offset = 0; for (int index = 0; index < cnt; index++) { var item = items[index]; byte[] bytes; if (item != null) { bytes = BitConverter.GetBytes((short)item.Length); offset += (short)item.Length; // write the body of item Buffer.BlockCopy(item, 0, content, contentLength - offset, item.Length); } else { bytes = zeroBytesShort; } // write the length marker Buffer.BlockCopy(bytes, 0, content, headerLength + OnPagePointerSize * (index + 1), sizeof(short)); } // write the length of length marker array byte[] lengthLengthMarkers = BitConverter.GetBytes((short)cnt); lengthLengthMarkers.CopyTo(content, headerLength); WriteFreeSpace(page, (ushort)remainingSpace); }
public static void InitPage(IPage page, PageHeaderBase header) { if (header.Length > page.Length) { throw new PageFormatException("Unable to format page. Too large header."); } // fill whole page with zero Array.Clear(page.Content, 0, page.Length); header.WriteToPage(page); }
public static void FormatFixedSizeItemsPage(IPage page, PageHeaderBase header, DbItem[] items) { var sizeRange = header.SizeRange; if (items.Any()) { if (items.Any(item => item.SizeRange != sizeRange)) { throw new ArgumentException("Size ranges should be equal", nameof(items)); } } header.WriteToPage(page); int remainingSpace = page.Length - // full page length header.Length - // subtract header length items.Length * OnPagePointerSize - OnPagePointerSize; // subtract item length markers array and its length if (remainingSpace < 0) { throw new ArgumentException("Page have no space to add specified items", nameof(items)); } var maxSize = DbItem.GetMaxSize(sizeRange); var content = page.Content; int contentLength = page.Length; int cnt = items.Length; int headerLength = header.Length; for (int index = 0; index < cnt; index++) { var rawData = items[index].RawData; // write the length marker Buffer.BlockCopy(BitConverter.GetBytes((short)rawData.Length), 0, content, headerLength + OnPagePointerSize * (index + 1), sizeof(short)); // write the body of item Buffer.BlockCopy(rawData, 0, content, contentLength - maxSize * (index + 1), rawData.Length); } // write the length of length marker array byte[] lengthLengthMarkers = BitConverter.GetBytes((short)cnt); lengthLengthMarkers.CopyTo(content, headerLength); }