Ejemplo n.º 1
0
        public FsmValue Get(long pageIndex)
        {
            if (!_isInitialized)
            {
                Init();
            }

            IPage page = GetFsmPageByTargetPageIndex(pageIndex);

            return(page == null
                ? FsmValue.Full :
                   PageFormatter.GetFsmValue(page, (int)pageIndex % _entryPerPage));
        }
Ejemplo n.º 2
0
        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));
            }
        }
Ejemplo n.º 3
0
        public long GetFreePageIndex(FsmValue value)
        {
            if (!_isInitialized)
            {
                Init();
            }

            // try to find in lucky pages
            if (_luckyFsmPages.ContainsKey(value))
            {
                IPage page = _luckyFsmPages[value].Page;

                var requestedFsmIndex = (int)(_luckyFsmPages[value].LastGoodIndex % _entryPerPage);
                int matchingFsmIndex;

                if (PageFormatter.GetFsmValue(page, requestedFsmIndex) == value)
                {
                    matchingFsmIndex = requestedFsmIndex;
                }
                else
                {
                    matchingFsmIndex = PageFormatter.GetIndexOfFirstMatchingFsmValue(page, value);
                    _luckyFsmPages[value].LastGoodIndex = matchingFsmIndex;
                }

                if (matchingFsmIndex == -1)
                {
                    // page becomes unlucky
                    _luckyFsmPages.Remove(value);
                }
                else
                {
                    return(PageFormatter.GetBasePageIndex(page) + matchingFsmIndex);
                }
            }

            var  currentPageIndex = _firstFsmPageIndex;
            long index            = 0;

            if (_scanned.Contains(value))
            {
                return(-1);
            }

            while (true)
            {
                // sequential scan all fsm pages for specified fsm-value
                var currentPage      = _pageManager.FetchPage(currentPageIndex);
                int matchingFsmIndex = PageFormatter.GetIndexOfFirstMatchingFsmValue(currentPage, value);
                if (matchingFsmIndex == -1)
                {
                    index += _entryPerPage;
                    var header = (FreeSpaceMapPageHeader)PageFormatter.GetPageHeader(currentPage);
                    if (header.NextPageIndex == -1)
                    {
                        _scanned.Add(value);
                        return(-1);
                    }

                    currentPageIndex = header.NextPageIndex;
                }
                else
                {
                    // make found page lucky
                    _luckyFsmPages[value] = new LuckyPage {
                        Page = currentPage, LastGoodIndex = matchingFsmIndex + index
                    };
                    return(index + matchingFsmIndex);
                }
            }
        }