Esempio n. 1
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);
                }
            }
        }