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); }
private byte *ReturnPagePointerOrGrowAllocation(LoadedPage page, long distanceFromStart, TransactionState state, bool canUnmap) { var pageHeader = (PageHeader *)(page.Pointer + (distanceFromStart * PageSize)); if ((pageHeader->Flags & PageFlags.Overflow) != PageFlags.Overflow) { // single page, already loaded, can return immediately. return((byte *)pageHeader); } // overflow, so need to make sure it is in the range we mapped. var numberOfOverflowPages = this.GetNumberOfOverflowPages(pageHeader->OverflowSize); if (numberOfOverflowPages + distanceFromStart < page.NumberOfPages) { // the entire range is already mapped, can return immediately return((byte *)pageHeader); } if (canUnmap) { Debug.Assert(state.AddressesToUnload[state.AddressesToUnload.Count - 1] == new IntPtr(page.Pointer)); state.AddressesToUnload.RemoveAt(state.AddressesToUnload.Count - 1); UnmapViewOfFile(page.Pointer); } var ammountToMapInBytes = NearestSizeToAllocationGranularity((distanceFromStart + numberOfOverflowPages) * PageSize); page = MapPages(state, page.StartPage, ammountToMapInBytes); return(page.Pointer + distanceFromStart * PageSize); }
private LoadedPage AddMappingToTransaction(TransactionState state, long startPage, long size, MappedAddresses mappedAddresses) { state.TotalLoadedSize += size; state.AddressesToUnload.Add(mappedAddresses); var loadedPage = new LoadedPage { Pointer = (byte *)mappedAddresses.Address, NumberOfPages = (int)(size / Constants.Storage.PageSize), StartPage = startPage }; state.LoadedPages[startPage] = loadedPage; return(loadedPage); }