예제 #1
0
        /// <summary>
        /// Releases db item by its reference
        /// </summary>
        /// <param name="reference">Reference to item to release</param>
        public void Free(DbItemReference reference)
        {
            IPage page   = _pageManager.FetchPage(reference.PageIndex);
            var   header = PageFormatter.GetPageHeader(page);

            if (header.SizeRange == SizeRange.MultiPage)
            {
                while (page != null)
                {
                    _pageManager.RemovePage(page.Index);
                    var nextPageIndex = ((MultipageItemPageHeader)PageFormatter.GetPageHeader(page)).NextPageIndex;
                    page = nextPageIndex == -1
                        ? null
                        : _pageManager.FetchPage(nextPageIndex);
                }
            }
            else
            {
                if (PageFormatter.ReadFixedSizeItemsCount(page) == 1)
                {
                    _pageManager.RemovePage(page.Index);
                    _fsm.Set(page.Index, FsmValue.Full);
                }
                else
                {
                    PageFormatter.DeleteFixedSizeItem(page, reference.ItemIndex);
                    _pageManager.UpdatePage(page);
                    _fsm.Set(page.Index, EnumHelper.FsmValueFromSizeRange(header.SizeRange));
                }
            }
        }
예제 #2
0
        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));
                }
            }
        }