public void InsertVariableSizeItemAfterDelete() { int pageSize = 4096; var dummyPageManager = new FileSystemPageManager(pageSize); var p = new Page(dummyPageManager, 0, new byte[pageSize]); var header = new RadixTreeNodesPageHeader { FreeSpace = (ushort)PageFormatter.GetMaximalFreeSpace((PageSize)p.Length) }; PageFormatter.InitPage(p, header); var r = new Random(); var items = new List <byte[]>(); var item = new byte[r.Next(100) + 1]; r.NextBytes(item); short itemIndex = 0; while (itemIndex != -1) { itemIndex = PageFormatter.AddVariableSizeItem(p, item); items.Add(item); item = new byte[r.Next(100) + 1]; r.NextBytes(item); } bool hasRemainingItems; // replace with the same PageFormatter.DeleteVariableSizeItem(p, 1, out hasRemainingItems); Assert.AreEqual(1, PageFormatter.AddVariableSizeItem(p, items[1])); item = PageFormatter.ReadVariableSizeItem(p, 1); Assert.IsTrue(AreEqualByteArrays(items[1], item)); // replace with smaller one PageFormatter.DeleteVariableSizeItem(p, 1, out hasRemainingItems); var smallItem = new byte[items[1].Length / 2 + 1]; r.NextBytes(smallItem); Assert.AreEqual(1, PageFormatter.AddVariableSizeItem(p, smallItem)); item = PageFormatter.ReadVariableSizeItem(p, 1); Assert.IsTrue(AreEqualByteArrays(smallItem, item)); // and put original again PageFormatter.DeleteVariableSizeItem(p, 1, out hasRemainingItems); PageFormatter.AddVariableSizeItem(p, items[1]); item = PageFormatter.ReadVariableSizeItem(p, 1); Assert.IsTrue(AreEqualByteArrays(items[1], item)); }
public void PageHasNoRemainingItemsAfterDelete() { int pageSize = 4096; var dummyPageManager = new FileSystemPageManager(pageSize); var p = new Page(dummyPageManager, 0, new byte[pageSize]); var header = new RadixTreeNodesPageHeader { FreeSpace = (ushort)PageFormatter.GetMaximalFreeSpace((PageSize)p.Length) }; PageFormatter.InitPage(p, header); var r = new Random(); var items = new List <byte[]>(); var item = new byte[r.Next(100) + 1]; r.NextBytes(item); short itemIndex = 0; while (itemIndex != -1) { itemIndex = PageFormatter.AddVariableSizeItem(p, item); if (itemIndex == -1) { continue; } items.Add(item); item = new byte[r.Next(100) + 1]; r.NextBytes(item); } bool hasRemainingItems; for (short i = 0; i < items.Count; i++) { PageFormatter.DeleteVariableSizeItem(p, i, out hasRemainingItems); if (i < items.Count - 1) { Assert.IsTrue(hasRemainingItems); } else { Assert.IsFalse(hasRemainingItems); } } }
private void InitFsmPage(IPage page, long previousPageIndex, long nextPageIndex, long basePageIndex) { var header = new FreeSpaceMapPageHeader { StartPageIndex = _firstFsmPageIndex, NextPageIndex = nextPageIndex, PreviousPageIndex = previousPageIndex, BasePageIndex = basePageIndex }; PageFormatter.InitPage(page, header); PageFormatter.SetAllFsmValues(page, FsmValue.Full); }
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)); } } }
private DbItemReference AllocateMultiPage(DbItem item) { long bytesWritten = 0; long startPageIndex = -1; DbItemReference result = null; IPage page = null; IPage previousPage = null; while (bytesWritten < item.RawData.LongLength) { page = _pageManager.CreatePage(); if (startPageIndex == -1) { startPageIndex = page.Index; result = new DbItemReference(page.Index, 0); } var header = new MultipageItemPageHeader { StartPageIndex = startPageIndex, PreviousPageIndex = previousPage?.Index ?? -1, NextPageIndex = -1, SizeRange = SizeRange.MultiPage }; PageFormatter.InitPage(page, header); bytesWritten += PageFormatter.WriteMultipageItemBlock(page, item, bytesWritten); if (previousPage != null) { header = (MultipageItemPageHeader)PageFormatter.GetPageHeader(previousPage); header.NextPageIndex = page.Index; header.WriteToPage(previousPage); _pageManager.UpdatePage(previousPage); } previousPage = page; } if (page != null) { _pageManager.UpdatePage(page); } return(result); }
public void ReadVariableSizeItems() { int pageSize = 4096; var dummyPageManager = new FileSystemPageManager(pageSize); var p = new Page(dummyPageManager, 0, new byte[pageSize]); var header = new RadixTreeNodesPageHeader { FreeSpace = (ushort)PageFormatter.GetMaximalFreeSpace((PageSize)p.Length) }; PageFormatter.InitPage(p, header); var r = new Random(); var items = new List <byte[]>(); var item = new byte[r.Next(100) + 1]; r.NextBytes(item); while (PageFormatter.AddVariableSizeItem(p, item) != -1) { items.Add(item); item = new byte[r.Next(100) + 1]; r.NextBytes(item); } for (short i = 0; i < items.Count; i++) { item = PageFormatter.ReadVariableSizeItem(p, i); Assert.IsTrue(AreEqualByteArrays(items[i], item)); } bool hasRemainingItems; PageFormatter.DeleteVariableSizeItem(p, 0, out hasRemainingItems); PageFormatter.DeleteVariableSizeItem(p, 2, out hasRemainingItems); PageFormatter.DeleteVariableSizeItem(p, (short)(items.Count - 1), out hasRemainingItems); Assert.Throws <PageFormatException>(() => PageFormatter.ReadVariableSizeItem(p, 0)); Assert.Throws <PageFormatException>(() => PageFormatter.ReadVariableSizeItem(p, 2)); Assert.Throws <PageFormatException>(() => PageFormatter.ReadVariableSizeItem(p, (short)(items.Count - 1))); }
protected override void Init() { base.Init(); //add access-method page IPage amPage = PageManager.CreatePage(); Debug.Assert(amPage.Index == 2, "The first access method page should have index 2"); var header = new RadixTreeNodesPageHeader { FreeSpace = (ushort)PageFormatter.GetMaximalFreeSpace((PageSize)PageManager.PageSize) }; PageFormatter.InitPage(amPage, header); PageManager.UpdatePage(amPage); }
private DbItemReference AllocateSinglePage(DbItem item) { DbItemReference result; IPage page; var fsmValue = EnumHelper.FsmValueFromSizeRange(item.SizeRange); var index = _fsm.GetFreePageIndex(fsmValue); bool spaceRemains; if (index != -1) { // place object to existing page page = _pageManager.FetchPage(index); result = PageFormatter.AddFixedSizeItem(page, item, out spaceRemains); if (!spaceRemains) { _fsm.Set(index, FsmValue.Full); } } else { // allocate on a new page page = _pageManager.CreatePage(); var header = new FixedSizeItemsPageHeader { SizeRange = item.SizeRange }; PageFormatter.InitPage(page, header); result = PageFormatter.AddFixedSizeItem(page, item, out spaceRemains); _fsm.Set(result.PageIndex, spaceRemains ? fsmValue : FsmValue.Full); } _pageManager.UpdatePage(page); return(result); }
protected override void Init() { base.Init(); //add access-method page IPage amPage = PageManager.CreatePage(); Debug.Assert(amPage.Index == 2, "The first access method page should have index 2"); var tnph = new BPlusTreeNodePageHeader { ParentPageIndex = -1, PreviousPageIndex = -1, NextPageIndex = -1, IsLeaf = true, SizeRange = DbItem.GetSizeRange(_maxKeySize + sizeof(Int64) + sizeof(Int16)) }; PageFormatter.InitPage(amPage, tnph); PageManager.UpdatePage(amPage); }
public void FsmPage() { int pageSize = 32768; var dummyPageManager = new FileSystemPageManager(pageSize); var p = new Page(dummyPageManager, 0, new byte[pageSize]); var fsmh = new FreeSpaceMapPageHeader(); var r = new Random(); PageFormatter.InitPage(p, fsmh); int fsmEntryCount = PageFormatter.GetFsmEntryCount(p); // set all values to "full" PageFormatter.SetAllFsmValues(p, FsmValue.Full); // check if all values are actually "full" for (int i = 0; i < fsmEntryCount; i++) { Assert.AreEqual(FsmValue.Full, PageFormatter.GetFsmValue(p, i)); } var values = new FsmValue[fsmEntryCount]; // set and keep random values for (int i = 0; i < fsmEntryCount; i++) { var value = (byte)r.Next((byte)FsmValue.Full + 1); PageFormatter.SetFsmValue(p, i, (FsmValue)value); values[i] = (FsmValue)value; } // compare it for (int i = 0; i < fsmEntryCount; i++) { Assert.AreEqual(values[i], PageFormatter.GetFsmValue(p, i)); } }
protected virtual void Init() { // add header page IPage headingPage = PageManager.CreatePage(); Debug.Assert(headingPage.Index == 0, "The header page should have zero index"); var hph = new HeadingPageHeader { FsmPageIndex = 1, AccessMethodPageIndex = 2, PageSize = PageManager.PageSize, OnDiskStructureVersion = OnDiskStructureVersion, AccessMethod = (short)AccessMethod }; PageFormatter.InitPage(headingPage, hph); PageManager.UpdatePage(headingPage); // add the first free-space-map page IPage fsmPage = PageManager.CreatePage(); Debug.Assert(fsmPage.Index == 1, "The first free-space-map page should have index 1"); var fsmh = new FreeSpaceMapPageHeader { StartPageIndex = fsmPage.Index, PreviousPageIndex = -1, NextPageIndex = -1, BasePageIndex = 0 }; PageFormatter.InitPage(fsmPage, fsmh); PageFormatter.SetAllFsmValues(fsmPage, FsmValue.Full); PageManager.UpdatePage(fsmPage); }
public void CorrectWriteAndReadAllHeaders() { int pageSize = 4096; var dummyPageManager = new FileSystemPageManager(pageSize); var p = new Page(dummyPageManager, 0, new byte[pageSize]); var hph = new HeadingPageHeader(); PageFormatter.InitPage(p, hph); PageHeaderBase phb = PageFormatter.GetPageHeader(p); Assert.IsInstanceOf <HeadingPageHeader>(phb); Assert.AreEqual(hph.Length, phb.Length); Assert.AreEqual(hph.PageType, phb.PageType); Assert.AreEqual(hph.SizeRange, phb.SizeRange); var fsiph = new FixedSizeItemsPageHeader(); PageFormatter.InitPage(p, fsiph); phb = PageFormatter.GetPageHeader(p); Assert.IsInstanceOf <FixedSizeItemsPageHeader>(phb); Assert.AreEqual(fsiph.Length, phb.Length); Assert.AreEqual(fsiph.PageType, phb.PageType); Assert.AreEqual(fsiph.SizeRange, phb.SizeRange); var mpph = new MultipageItemPageHeader(); PageFormatter.InitPage(p, mpph); phb = PageFormatter.GetPageHeader(p); Assert.IsInstanceOf <MultipageItemPageHeader>(phb); Assert.AreEqual(mpph.Length, phb.Length); Assert.AreEqual(mpph.PageType, phb.PageType); Assert.AreEqual(mpph.SizeRange, phb.SizeRange); Assert.AreEqual(mpph.StartPageIndex, ((MultipageItemPageHeader)phb).StartPageIndex); Assert.AreEqual(mpph.PreviousPageIndex, ((MultipageItemPageHeader)phb).PreviousPageIndex); Assert.AreEqual(mpph.NextPageIndex, ((MultipageItemPageHeader)phb).NextPageIndex); var fsmph = new FreeSpaceMapPageHeader(); PageFormatter.InitPage(p, fsmph); phb = PageFormatter.GetPageHeader(p); Assert.IsInstanceOf <FreeSpaceMapPageHeader>(phb); Assert.AreEqual(fsmph.Length, phb.Length); Assert.AreEqual(fsmph.PageType, phb.PageType); Assert.AreEqual(fsmph.SizeRange, phb.SizeRange); Assert.AreEqual(fsmph.BasePageIndex, ((FreeSpaceMapPageHeader)phb).BasePageIndex); var tnph = new BPlusTreeNodePageHeader(); PageFormatter.InitPage(p, tnph); phb = PageFormatter.GetPageHeader(p); Assert.IsInstanceOf <BPlusTreeNodePageHeader>(phb); Assert.AreEqual(tnph.Length, phb.Length); Assert.AreEqual(tnph.PageType, phb.PageType); Assert.AreEqual(tnph.SizeRange, phb.SizeRange); Assert.AreEqual(tnph.ParentPageIndex, ((BPlusTreeNodePageHeader)phb).ParentPageIndex); Assert.AreEqual(tnph.PreviousPageIndex, ((BPlusTreeNodePageHeader)phb).PreviousPageIndex); Assert.AreEqual(tnph.NextPageIndex, ((BPlusTreeNodePageHeader)phb).NextPageIndex); var rtnph = new RadixTreeNodesPageHeader(); PageFormatter.InitPage(p, rtnph); phb = PageFormatter.GetPageHeader(p); Assert.IsInstanceOf <RadixTreeNodesPageHeader>(phb); Assert.AreEqual(rtnph.Length, phb.Length); Assert.AreEqual(rtnph.PageType, phb.PageType); Assert.AreEqual(rtnph.SizeRange, phb.SizeRange); Assert.AreEqual(rtnph.FreeSpace, ((RadixTreeNodesPageHeader)phb).FreeSpace); }