public void FixedSizeItemsPage() { int pageSize = 32768; var dummyPageManager = new FileSystemPageManager(pageSize); var p = new Page(dummyPageManager, 0, new byte[pageSize]); var header = new FixedSizeItemsPageHeader(); var r = new Random(); foreach (var sizeRange in EnumHelper.FixedSizeItemsSizeRanges()) { header.SizeRange = sizeRange; PageFormatter.InitPage(p, header); var item = new DbItem(new byte[DbItem.GetMaxSize(header.SizeRange)]); r.NextBytes(item.RawData); // fill the page with the items short count = 0; bool spaceRemains = true; while (PageFormatter.HasFreeSpaceForFixedSizeItem(p)) { Assert.IsTrue(spaceRemains); PageFormatter.AddFixedSizeItem(p, item, out spaceRemains); count++; Assert.AreEqual(count, PageFormatter.ReadFixedSizeItemsCount(p)); } Assert.IsFalse(spaceRemains); // check if fetched objects are equal to originals for (short j = 0; j < PageFormatter.ReadFixedSizeItemsCount(p); j++) { DbItem readItem = PageFormatter.ReadFixedSizeItem(p, j); Assert.IsTrue(AreEqualByteArrays(item.RawData, readItem.RawData)); } // delete all added items short itemindex = 0; while (PageFormatter.ReadFixedSizeItemsCount(p) > 0) { PageFormatter.DeleteFixedSizeItem(p, itemindex); count--; itemindex++; Assert.AreEqual(count, PageFormatter.ReadFixedSizeItemsCount(p)); } } }
/// <summary> /// Gets DbItem instance by reference. /// </summary> /// <param name="reference">Reference to the requested db item</param> /// <returns></returns> public DbItem Get(DbItemReference reference) { if (!_pageManager.PageExists(reference.PageIndex)) { return(null); } IPage page = _pageManager.FetchPage(reference.PageIndex); var header = PageFormatter.GetPageHeader(page); if (header.SizeRange == SizeRange.MultiPage) { var length = PageFormatter.ReadMultipageItemLength(page); var content = new byte[length]; long offset = 0; while (page != null) { var readBytes = PageFormatter.ReadMultipageItemBlock(page, Math.Min(_pageManager.PageSize, (int)(length - offset))); readBytes.CopyTo(content, offset); offset += readBytes.Length; var nextPageIndex = ((MultipageItemPageHeader)header).NextPageIndex; if (nextPageIndex != -1) { page = _pageManager.FetchPage(nextPageIndex); header = PageFormatter.GetPageHeader(page); } else { page = null; } } return(new DbItem(content)); } return(PageFormatter.IsFixedSizeItemAllocated(page, reference.ItemIndex) ? PageFormatter.ReadFixedSizeItem(page, reference.ItemIndex) : null); }
private byte[] GetFixedSizeItemSegment(IPage page, DbItemReference reference, long startIndex, long endIndex) { if (!PageFormatter.IsFixedSizeItemAllocated(page, reference.ItemIndex)) { return new byte[] { } } ; var item = PageFormatter.ReadFixedSizeItem(page, reference.ItemIndex); if (item.RawData.Length >= endIndex) { throw new ArgumentOutOfRangeException(nameof(endIndex)); } var length = endIndex - startIndex + 1; var result = new byte[length]; Array.Copy(item.RawData, startIndex, result, 0, length); return(result); }