public FsmValue Get(long pageIndex) { if (!_isInitialized) { Init(); } IPage page = GetFsmPageByTargetPageIndex(pageIndex); return(page == null ? FsmValue.Full : PageFormatter.GetFsmValue(page, (int)pageIndex % _entryPerPage)); }
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)); } }
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); } } }