Пример #1
0
        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();
        }
Пример #2
0
		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));
		}
Пример #4
0
 internal void EnsurePagerStateReference(PagerState state)
 {
     if (_pagerStates.Add(state))
         state.AddRef();
 }
Пример #5
0
 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;
		}
Пример #7
0
 public Page ReadPage(long p, PagerState pagerState = null)
 {
     return _scratchPager.Read(p, pagerState);
 }
Пример #8
0
 public PagerStateCacheItem( int file, PagerState state )
 {
     this.FileNumber = file;
     this.State = state;
 }
Пример #9
0
 public PagerStateCacheItem(int file, PagerState state)
 {
     this.FileNumber = file;
     this.State      = state;
 }
Пример #10
0
 public PagerStateCacheItem(int file, PagerState state)
 {
     FileNumber = file;
     State      = state;
 }
Пример #11
0
 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);
 }
Пример #12
0
 public void AddPagerState(PagerState state)
 {
     LatestPagerState = state;
     _pagerStates.Add(state);
 }
Пример #13
0
 public Page ReadPage(long p, PagerState pagerState = null)
 {
     return(_scratchPager.Read(p, pagerState));
 }
Пример #14
0
 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);
		}
Пример #17
0
 public override void Dispose()
 {
     base.Dispose();
     PagerState.Release();
     _base = null;
 }
Пример #18
0
		internal void AddPagerState(PagerState state)
		{
			_pagerStates.Add(state);
		}
Пример #19
0
 public void AddPagerState(PagerState state)
 {
     _pagerStates.Add(state);
 }
Пример #20
0
        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;
        }
Пример #21
0
 internal void AddPagerState(PagerState state)
 {
     LatestPagerState = state;
     _pagerStates.Add(state);
 }
Пример #22
0
		public override byte* AcquirePagePointer(long pageNumber, PagerState pagerState = null)
		{
			ThrowObjectDisposedIfNeeded();

			return (pagerState ?? PagerState).MapBase + (pageNumber*PageSize);
		}
Пример #23
0
		public void AddPagerState(PagerState state)
		{
			LatestPagerState = state;
			_pagerStates.Add(state);
		}