public Transaction(StorageEnvironment env, long id, TransactionFlags flags, IFreeSpaceHandling freeSpaceHandling) { _dataPager = env.Options.DataPager; _env = env; _journal = env.Journal; _id = id; _freeSpaceHandling = freeSpaceHandling; Flags = flags; var scratchPagerState = env.ScratchBufferPool.PagerState; scratchPagerState.AddRef(); _pagerStates.Add(scratchPagerState); if (flags.HasFlag(TransactionFlags.ReadWrite) == false) { // for read transactions, we need to keep the pager state frozen // for write transactions, we can use the current one (which == null) _scratchPagerState = scratchPagerState; _state = env.State.Clone(this); _journal.GetSnapshots().ForEach(AddJournalSnapshot); return; } _state = env.State.Clone(this); InitTransactionHeader(); MarkTreesForWriteTransaction(); }
private PagerState CreateNewPagerState() { var mmf = MemoryMappedFile.CreateFromFile(_fileStream, Guid.NewGuid().ToString(), _fileStream.Length, MemoryMappedFileAccess.ReadWrite, null, HandleInheritability.None, true); var accessor = mmf.CreateViewAccessor(); byte* p = null; accessor.SafeMemoryMappedViewHandle.AcquirePointer(ref p); var newPager = new PagerState { Accessor = accessor, File = mmf, Base = p }; newPager.AddRef(); // one for the pager return newPager; }
private PagerState AllocateMorePagesAndRemapContinuously(long allocationSize) { var retryCount = 0; while (retryCount++ < MaxAllocationRetries) { byte* newBaseAddress; if (TryFindContinuousMemory((ulong)(_totalAllocationSize + allocationSize), out newBaseAddress) == false) { var message = string.Format( "Unable to allocate more pages - unsuccessfully tried to allocate continuous block of size = {0} bytes\r\n" + "It is likely that we are suffering from virtual memory exhaustion or memory fragmentation.\r\n" + "64 bits process: {1}\r\n" + "If you are running in 32 bits, this is expected, and you need to run in 64 bits to resume normal operations.\r\n" + "If you are running in 64 bits, this is likely an error and should be reported." , (_totalAllocationSize + allocationSize), Environment.Is64BitProcess); throw new OutOfMemoryException(message); } bool failedToAllocate = false; long offset = 0; var allocationInfoAfterReallocation = new List<PagerState.AllocationInfo>(); foreach (var allocationInfo in PagerState.AllocationInfos) { var newAlloctedBaseAddress = Win32MemoryMapNativeMethods.MapViewOfFileEx(allocationInfo.MappedFile.SafeMemoryMappedFileHandle.DangerousGetHandle(), Win32MemoryMapNativeMethods.NativeFileMapAccessType.Read | Win32MemoryMapNativeMethods.NativeFileMapAccessType.Write, 0, 0, UIntPtr.Zero, newBaseAddress + offset); if (newAlloctedBaseAddress == null || newAlloctedBaseAddress == (byte*)0) { Debug.WriteLine("Failed to remap file continuously. Unmapping already mapped files and re-trying"); UndoMappings(allocationInfoAfterReallocation); failedToAllocate = true; break; } offset += allocationInfo.Size; allocationInfoAfterReallocation.Add(new PagerState.AllocationInfo { BaseAddress = newAlloctedBaseAddress, MappedFile = allocationInfo.MappedFile, Size = allocationInfo.Size }); } if (failedToAllocate) continue; var newAllocationInfo = TryCreateNewFileMappingAtAddress(allocationSize, newBaseAddress + _totalAllocationSize); if (newAllocationInfo == null) { UndoMappings(allocationInfoAfterReallocation); continue; } var newPagerState = new PagerState(this) { Files = PagerState.Files.Concat(newAllocationInfo.MappedFile), AllocationInfos = allocationInfoAfterReallocation.Concat(newAllocationInfo), MapBase = newBaseAddress }; return newPagerState; } throw new InvalidOperationException( string.Format( "Something bad has happened, after {0} tries, could not find any spot in virtual memory to remap continuous virtual memory for {1:##,###;;0} bytes", MaxAllocationRetries, allocationSize)); }
internal void EnsurePagerStateReference(PagerState state) { if (_pagerStates.Add(state)) state.AddRef(); }
internal void AddPagerState(PagerState state) { LatestPagerState = state; _pagerStates.Add(state); }
private PagerState CreatePagerState() { var mmf = MemoryMappedFile.CreateFromFile(_fileStream, null, _fileStream.Length, _memoryMappedFileAccess, null, HandleInheritability.None, true); var fileMappingHandle = mmf.SafeMemoryMappedFileHandle.DangerousGetHandle(); var mmFileAccessType = _access == Win32NativeFileAccess.GenericRead ? Win32MemoryMapNativeMethods.NativeFileMapAccessType.Read : Win32MemoryMapNativeMethods.NativeFileMapAccessType.Read | Win32MemoryMapNativeMethods.NativeFileMapAccessType.Write; var startingBaseAddressPtr = Win32MemoryMapNativeMethods.MapViewOfFileEx(fileMappingHandle, mmFileAccessType, 0, 0, UIntPtr.Zero, //map all what was "reserved" in CreateFileMapping on previous row null); if (startingBaseAddressPtr == (byte*)0) //system didn't succeed in mapping the address where we wanted throw new Win32Exception(); var allocationInfo = new PagerState.AllocationInfo { BaseAddress = startingBaseAddressPtr, Size = _fileStream.Length, MappedFile = mmf }; var newPager = new PagerState(this) { Files = new[] { mmf }, MapBase = startingBaseAddressPtr, AllocationInfos = new[] { allocationInfo } }; newPager.AddRef(); // one for the pager return newPager; }
public Page ReadPage(long p, PagerState pagerState = null) { return _scratchPager.Read(p, pagerState); }
public PagerStateCacheItem( int file, PagerState state ) { this.FileNumber = file; this.State = state; }
public PagerStateCacheItem(int file, PagerState state) { this.FileNumber = file; this.State = state; }
public PagerStateCacheItem(int file, PagerState state) { FileNumber = file; State = state; }
public void CopyPrefetchState(PagerState olderInstance) { // this is called from AllocateMorePages and is used to copy the current state of the // prefetch state of the file. Our own size will be larger than the previous one. Array.Copy(olderInstance._prefetchTable, this._prefetchTable, olderInstance._prefetchTable.Length); }
public void AddPagerState(PagerState state) { LatestPagerState = state; _pagerStates.Add(state); }
public Page ReadPage(long p, PagerState pagerState = null) { return(_scratchPager.Read(p, pagerState)); }
internal void AddPagerState(PagerState state) { _pagerStates.Add(state); }
private PagerState CreateInitialPagerState(long size) { var allocationSize = NearestSizeToAllocationGranularity(size); var mmf = MemoryMappedFile.CreateNew(null, allocationSize, MemoryMappedFileAccess.ReadWrite); var fileMappingHandle = mmf.SafeMemoryMappedFileHandle.DangerousGetHandle(); var startingBaseAddressPtr = Win32MemoryMapNativeMethods.MapViewOfFileEx(fileMappingHandle, Win32MemoryMapNativeMethods.NativeFileMapAccessType.Read | Win32MemoryMapNativeMethods.NativeFileMapAccessType.Write, 0, 0, UIntPtr.Zero, //map all what was "reserved" in CreateFileMapping on previous row null); if (startingBaseAddressPtr == (byte*)0) //system didn't succeed in mapping the address where we wanted throw new Win32Exception(); var allocationInfo = new PagerState.AllocationInfo { BaseAddress = startingBaseAddressPtr, Size = allocationSize, MappedFile = mmf }; var newPager = new PagerState(this) { Files = new[] { mmf }, MapBase = startingBaseAddressPtr, AllocationInfos = new[] { allocationInfo } }; newPager.AddRef(); return newPager; }
public override byte* AcquirePagePointer(long pageNumber, PagerState pagerState = null) { return (pagerState ?? PagerState).MapBase + (pageNumber * PageSize); }
public override void Dispose() { base.Dispose(); PagerState.Release(); _base = null; }
public void AddPagerState(PagerState state) { _pagerStates.Add(state); }
private PagerState CreatePagerState() { var startingBaseAddressPtr = Syscall.mmap(IntPtr.Zero, (ulong)_totalAllocationSize, MmapProts.PROT_READ | MmapProts.PROT_WRITE, MmapFlags.MAP_SHARED, _fd, 0); if (startingBaseAddressPtr.ToInt64() == -1) //system didn't succeed in mapping the address where we wanted PosixHelper.ThrowLastError(Marshal.GetLastWin32Error()); var allocationInfo = new PagerState.AllocationInfo { BaseAddress = (byte*)startingBaseAddressPtr.ToPointer(), Size = _totalAllocationSize, MappedFile = null }; var newPager = new PagerState(this) { Files = null, // unused MapBase = allocationInfo.BaseAddress, AllocationInfos = new[] { allocationInfo } }; newPager.AddRef(); // one for the pager return newPager; }
public override byte* AcquirePagePointer(long pageNumber, PagerState pagerState = null) { ThrowObjectDisposedIfNeeded(); return (pagerState ?? PagerState).MapBase + (pageNumber*PageSize); }