private LoadedPage MapPages(TransactionState state, long startPage, long size) { var offset = new Win32MemoryMapPager.SplitValue { Value = (ulong)startPage * (ulong)PageSize }; if ((long)offset.Value + size > _fileStreamLength) { size = _fileStreamLength - (long)offset.Value; } var result = MapViewOfFileEx(_hFileMappingObject, _mmFileAccessType, offset.High, offset.Low, (UIntPtr)size, null); if (result == null) { throw new Win32Exception(); } state.AddressesToUnload.Add(new IntPtr(result)); var loadedPage = new LoadedPage { Pointer = result, NumberOfPages = (int)(size / PageSize), StartPage = startPage }; state.LoadedPages[startPage] = loadedPage; return(loadedPage); }
public override int CopyPage(IPagerBatchWrites destPagerBatchWrites, long pageNumber, PagerState pagerState) { var distanceFromStart = (pageNumber % 16); var allocationStartPosition = pageNumber - distanceFromStart; var offset = new Win32MemoryMapPager.SplitValue { Value = (ulong)allocationStartPosition * (ulong)PageSize }; var result = MapViewOfFileEx(_hFileMappingObject, _mmFileAccessType, offset.High, offset.Low, (UIntPtr)(16 * PageSize), null); if (result == null) { throw new Win32Exception(); } var pageHeader = (PageHeader *)(result + distanceFromStart * PageSize); int numberOfPages = 1; if ((pageHeader->Flags & PageFlags.Overflow) == PageFlags.Overflow) { numberOfPages = this.GetNumberOfOverflowPages(pageHeader->OverflowSize); } if (numberOfPages + distanceFromStart > 16) { UnmapViewOfFile(result); result = MapViewOfFileEx(_hFileMappingObject, _mmFileAccessType, offset.High, offset.Low, (UIntPtr)(NearestSizeToAllocationGranularity((numberOfPages + distanceFromStart) * PageSize)), null); if (result == null) { throw new Win32Exception(); } pageHeader = (PageHeader *)(result + (distanceFromStart * PageSize)); } destPagerBatchWrites.Write(pageHeader->PageNumber, numberOfPages, (byte *)pageHeader); UnmapViewOfFile(result); return(numberOfPages); }