public Win32MemoryMapPager(int pageSize, string file,
                                   long?initialFileSize = null,
                                   Win32NativeFileAttributes options = Win32NativeFileAttributes.Normal,
                                   Win32NativeFileAccess access      = Win32NativeFileAccess.GenericRead | Win32NativeFileAccess.GenericWrite)
            : base(pageSize)
        {
            Win32NativeMethods.SYSTEM_INFO systemInfo;
            Win32NativeMethods.GetSystemInfo(out systemInfo);

            AllocationGranularity = systemInfo.allocationGranularity;

            _access = access;
            _memoryMappedFileAccess = _access == Win32NativeFileAccess.GenericRead
                ? MemoryMappedFileAccess.Read
                : MemoryMappedFileAccess.ReadWrite;

            _handle = Win32NativeFileMethods.CreateFile(file, access,
                                                        Win32NativeFileShare.Read | Win32NativeFileShare.Write | Win32NativeFileShare.Delete, IntPtr.Zero,
                                                        Win32NativeFileCreationDisposition.OpenAlways, options, IntPtr.Zero);
            if (_handle.IsInvalid)
            {
                int lastWin32ErrorCode = Marshal.GetLastWin32Error();
                throw new IOException("Failed to open file storage of Win32MemoryMapPager for " + file,
                                      new Win32Exception(lastWin32ErrorCode));
            }

            _fileInfo = new FileInfo(file);

            var streamAccessType = _access == Win32NativeFileAccess.GenericRead
                ? FileAccess.Read
                : FileAccess.ReadWrite;

            _fileStream = new FileStream(_handle, streamAccessType);

            _totalAllocationSize = _fileInfo.Length;

            if (_access.HasFlag(Win32NativeFileAccess.GenericWrite) ||
                _access.HasFlag(Win32NativeFileAccess.GenericAll) ||
                _access.HasFlag(Win32NativeFileAccess.FILE_GENERIC_WRITE))
            {
                var fileLength = _fileStream.Length;
                if (fileLength == 0 && initialFileSize.HasValue)
                {
                    fileLength = initialFileSize.Value;
                }

                if (_fileStream.Length == 0 || (fileLength % AllocationGranularity != 0))
                {
                    fileLength = NearestSizeToAllocationGranularity(fileLength);

                    Win32NativeFileMethods.SetFileLength(_handle, fileLength);
                }

                _totalAllocationSize = fileLength;
            }

            NumberOfAllocatedPages = _totalAllocationSize / _pageSize;
            PagerState.Release();
            PagerState = CreatePagerState();
        }
Beispiel #2
0
        public Win32FileJournalWriter(StorageEnvironmentOptions options, VoronPathSetting filename, long journalSize,
                                      Win32NativeFileAccess access   = Win32NativeFileAccess.GenericWrite,
                                      Win32NativeFileShare shareMode = Win32NativeFileShare.Read)
        {
            try
            {
                _options  = options;
                _filename = filename;
                _handle   = Win32NativeFileMethods.CreateFile(filename.FullPath,
                                                              access, shareMode, IntPtr.Zero,
                                                              Win32NativeFileCreationDisposition.OpenAlways,
                                                              options.WinOpenFlags, IntPtr.Zero);

                if (_handle.IsInvalid)
                {
                    throw new IOException("When opening file " + filename, new Win32Exception(Marshal.GetLastWin32Error()));
                }

                var length = new FileInfo(filename.FullPath).Length;
                if (length < journalSize)
                {
                    try
                    {
                        Win32NativeFileMethods.SetFileLength(_handle, journalSize);
                    }
                    catch (Exception)
                    {
                        try
                        {
                            _handle?.Dispose();
                            _handle = null;
                            File.Delete(_filename.FullPath);
                        }
                        catch (Exception)
                        {
                            // there's nothing we can do about it
                        }

                        throw;
                    }

                    length = journalSize;
                }

                NumberOfAllocated4Kb = (int)(length / (4 * Constants.Size.Kilobyte));

                _nativeOverlapped = (NativeOverlapped *)NativeMemory.AllocateMemory(sizeof(NativeOverlapped));

                _nativeOverlapped->InternalLow  = IntPtr.Zero;
                _nativeOverlapped->InternalHigh = IntPtr.Zero;
            }
            catch
            {
                Dispose();
                throw;
            }
        }
		public Win32MemoryMapPager(string file,
			long? initialFileSize = null,
		                           Win32NativeFileAttributes options = Win32NativeFileAttributes.Normal,
		                           Win32NativeFileAccess access = Win32NativeFileAccess.GenericRead | Win32NativeFileAccess.GenericWrite)
		{
			Win32NativeMethods.SYSTEM_INFO systemInfo;
			Win32NativeMethods.GetSystemInfo(out systemInfo);

			AllocationGranularity = systemInfo.allocationGranularity;

			_access = access;
			_memoryMappedFileAccess = _access == Win32NativeFileAccess.GenericRead
				? MemoryMappedFileAccess.Read
				: MemoryMappedFileAccess.ReadWrite;

			_handle = Win32NativeFileMethods.CreateFile(file, access,
			                                            Win32NativeFileShare.Read | Win32NativeFileShare.Write | Win32NativeFileShare.Delete, IntPtr.Zero,
			                                            Win32NativeFileCreationDisposition.OpenAlways, options, IntPtr.Zero);
			if (_handle.IsInvalid)
			{
				int lastWin32ErrorCode = Marshal.GetLastWin32Error();
				throw new IOException("Failed to open file storage of Win32MemoryMapPager",
					new Win32Exception(lastWin32ErrorCode));
			}

			_fileInfo = new FileInfo(file);

			var streamAccessType = _access == Win32NativeFileAccess.GenericRead
				? FileAccess.Read
				: FileAccess.ReadWrite;
			_fileStream = new FileStream(_handle, streamAccessType);

			_totalAllocationSize = _fileInfo.Length;

			if (_access.HasFlag(Win32NativeFileAccess.GenericWrite) || 
			    _access.HasFlag(Win32NativeFileAccess.GenericAll) ||
			    _access.HasFlag(Win32NativeFileAccess.FILE_GENERIC_WRITE))
			{
				var fileLength = _fileStream.Length;
				if (fileLength == 0 && initialFileSize.HasValue)
					fileLength = initialFileSize.Value;

				if (_fileStream.Length == 0 || (fileLength % AllocationGranularity != 0))
				{
					fileLength = NearestSizeToAllocationGranularity(fileLength);

					Win32NativeFileMethods.SetFileLength(_handle, fileLength);
				}

				_totalAllocationSize = fileLength;
			}

			NumberOfAllocatedPages = _totalAllocationSize / PageSize;
			PagerState.Release();
			PagerState = CreatePagerState();
		}
        public WindowsMemoryMapPager(StorageEnvironmentOptions options, VoronPathSetting file,
                                     long?initialFileSize = null,
                                     Win32NativeFileAttributes fileAttributes = Win32NativeFileAttributes.Normal,
                                     Win32NativeFileAccess access             = Win32NativeFileAccess.GenericRead | Win32NativeFileAccess.GenericWrite,
                                     bool usePageProtection = false)
            : base(options, !fileAttributes.HasFlag(Win32NativeFileAttributes.Temporary), usePageProtection)
        {
            SYSTEM_INFO systemInfo;

            GetSystemInfo(out systemInfo);
            FileName = file;
            _logger  = LoggingSource.Instance.GetLogger <StorageEnvironment>($"Pager-{file}");

            _access          = access;
            _copyOnWriteMode = Options.CopyOnWriteMode && FileName.FullPath.EndsWith(Constants.DatabaseFilename);
            if (_copyOnWriteMode)
            {
                _memoryMappedFileAccess = MemoryMappedFileAccess.Read | MemoryMappedFileAccess.CopyOnWrite;
                fileAttributes          = Win32NativeFileAttributes.Readonly;
                _access = Win32NativeFileAccess.GenericRead;
            }
            else
            {
                _memoryMappedFileAccess = _access == Win32NativeFileAccess.GenericRead
                ? MemoryMappedFileAccess.Read
                : MemoryMappedFileAccess.ReadWrite;
            }
            _fileAttributes = fileAttributes;

            _handle = Win32NativeFileMethods.CreateFile(file.FullPath, access,
                                                        Win32NativeFileShare.Read | Win32NativeFileShare.Write | Win32NativeFileShare.Delete, IntPtr.Zero,
                                                        Win32NativeFileCreationDisposition.OpenAlways, fileAttributes, IntPtr.Zero);
            if (_handle.IsInvalid)
            {
                int lastWin32ErrorCode = Marshal.GetLastWin32Error();
                throw new IOException("Failed to open file storage of WinMemoryMapPager for " + file,
                                      new Win32Exception(lastWin32ErrorCode));
            }

            _fileInfo = new FileInfo(file.FullPath);
            var drive = _fileInfo.Directory.Root.Name.TrimEnd('\\');

            try
            {
                if (PhysicalDrivePerMountCache.TryGetValue(drive, out UniquePhysicalDriveId) == false)
                {
                    UniquePhysicalDriveId = GetPhysicalDriveId(drive);
                }

                if (_logger.IsInfoEnabled)
                {
                    _logger.Info($"Physical drive '{drive}' unique id = '{UniquePhysicalDriveId}' for file '{file}'");
                }
            }
            catch (Exception ex)
            {
                UniquePhysicalDriveId = 0;
                if (_logger.IsInfoEnabled)
                {
                    _logger.Info($"Failed to determine physical drive Id for drive letter '{drive}', file='{file}'", ex);
                }
            }

            var streamAccessType = _access == Win32NativeFileAccess.GenericRead
                ? FileAccess.Read
                : FileAccess.ReadWrite;

            _fileStream = SafeFileStream.Create(_handle, streamAccessType);

            _totalAllocationSize = _fileInfo.Length;

            if ((access & Win32NativeFileAccess.GenericWrite) == Win32NativeFileAccess.GenericWrite ||
                (access & Win32NativeFileAccess.GenericAll) == Win32NativeFileAccess.GenericAll ||
                (access & Win32NativeFileAccess.FILE_GENERIC_WRITE) == Win32NativeFileAccess.FILE_GENERIC_WRITE)
            {
                var fileLength = _fileStream.Length;
                if (fileLength == 0 && initialFileSize.HasValue)
                {
                    fileLength = initialFileSize.Value;
                }

                if (_fileStream.Length == 0 || (fileLength % AllocationGranularity != 0))
                {
                    fileLength = NearestSizeToAllocationGranularity(fileLength);

                    Win32NativeFileMethods.SetFileLength(_handle, fileLength);
                }

                _totalAllocationSize = fileLength;
            }

            NumberOfAllocatedPages = _totalAllocationSize / Constants.Storage.PageSize;

            SetPagerState(CreatePagerState());
        }
Beispiel #5
0
        public Windows32BitsMemoryMapPager(StorageEnvironmentOptions options, VoronPathSetting file, long?initialFileSize = null,
                                           Win32NativeFileAttributes fileAttributes = Win32NativeFileAttributes.Normal,
                                           Win32NativeFileAccess access             = Win32NativeFileAccess.GenericRead | Win32NativeFileAccess.GenericWrite,
                                           bool usePageProtection = false)
            : base(options, canPrefetchAhead: false, usePageProtection: usePageProtection)
        {
            _memoryMappedFileAccess = access == Win32NativeFileAccess.GenericRead
              ? MemoryMappedFileAccess.Read
              : MemoryMappedFileAccess.ReadWrite;

            _mmFileAccessType = access == Win32NativeFileAccess.GenericRead
                ? NativeFileMapAccessType.Read
                : NativeFileMapAccessType.Read |
                                NativeFileMapAccessType.Write;

            FileName = file;

            if (Options.CopyOnWriteMode)
            {
                ThrowNotSupportedOption(file.FullPath);
            }

            _fileAttributes = fileAttributes;
            _handle         = CreateFile(file.FullPath, access,
                                         Win32NativeFileShare.Read | Win32NativeFileShare.Write | Win32NativeFileShare.Delete, IntPtr.Zero,
                                         Win32NativeFileCreationDisposition.OpenAlways,
                                         fileAttributes, IntPtr.Zero);


            if (_handle.IsInvalid)
            {
                var lastWin32ErrorCode = Marshal.GetLastWin32Error();
                throw new IOException("Failed to open file storage of Windows32BitsMemoryMapPager for " + file,
                                      new Win32Exception(lastWin32ErrorCode));
            }

            _fileInfo = new FileInfo(file.FullPath);

            var streamAccessType = access == Win32NativeFileAccess.GenericRead
                 ? FileAccess.Read
                 : FileAccess.ReadWrite;

            _fileStream = SafeFileStream.Create(_handle, streamAccessType);

            _totalAllocationSize = _fileInfo.Length;

            if ((access & Win32NativeFileAccess.GenericWrite) == Win32NativeFileAccess.GenericWrite ||
                (access & Win32NativeFileAccess.GenericAll) == Win32NativeFileAccess.GenericAll ||
                (access & Win32NativeFileAccess.FILE_GENERIC_WRITE) == Win32NativeFileAccess.FILE_GENERIC_WRITE)
            {
                var fileLength = _fileStream.Length;
                if ((fileLength == 0) && initialFileSize.HasValue)
                {
                    fileLength = initialFileSize.Value;
                }

                if ((_fileStream.Length == 0) || (fileLength % AllocationGranularity != 0))
                {
                    fileLength = NearestSizeToAllocationGranularity(fileLength);

                    SetFileLength(_handle, fileLength, file.FullPath);
                }
                _totalAllocationSize = fileLength;
            }

            NumberOfAllocatedPages = _totalAllocationSize / Constants.Storage.PageSize;
            SetPagerState(CreatePagerState());
        }
        public static extern SafeFileHandle CreateFile(string lpFileName,
		                                               Win32NativeFileAccess dwDesiredAccess, Win32NativeFileShare dwShareMode,
		                                               IntPtr lpSecurityAttributes,
		                                               Win32NativeFileCreationDisposition dwCreationDisposition,
		                                               Win32NativeFileAttributes dwFlagsAndAttributes, IntPtr hTemplateFile);
Beispiel #7
0
 public static extern SafeFileHandle CreateFile(string lpFileName,
                                                Win32NativeFileAccess dwDesiredAccess, Win32NativeFileShare dwShareMode,
                                                IntPtr lpSecurityAttributes,
                                                Win32NativeFileCreationDisposition dwCreationDisposition,
                                                Win32NativeFileAttributes dwFlagsAndAttributes, IntPtr hTemplateFile);
Beispiel #8
0
        public SparseMemoryMappedPager(StorageEnvironmentOptions options, string file, long?initialFileSize = null,
                                       Win32NativeFileAttributes fileAttributes = Win32NativeFileAttributes.Normal,
                                       Win32NativeFileAccess access             = Win32NativeFileAccess.GenericRead | Win32NativeFileAccess.GenericWrite)
            : base(options)
        {
            _memoryMappedFileAccess = access == Win32NativeFileAccess.GenericRead
              ? MemoryMappedFileAccess.Read
              : MemoryMappedFileAccess.ReadWrite;

            _mmFileAccessType = access == Win32NativeFileAccess.GenericRead
                ? NativeFileMapAccessType.Read
                : NativeFileMapAccessType.Read |
                                NativeFileMapAccessType.Write;

            FileName = file;
            _logger  = LoggingSource.Instance.GetLogger <StorageEnvironment>($"Pager-{file}");

            if (Options.CopyOnWriteMode)
            {
                throw new NotImplementedException("CopyOnWriteMode using spare memory is currently not supported on " +
                                                  file);
            }

            SYSTEM_INFO info;

            GetSystemInfo(out info);
            AllocationGranularity = info.allocationGranularity;

            _handle = CreateFile(file, access,
                                 Win32NativeFileShare.Read | Win32NativeFileShare.Write | Win32NativeFileShare.Delete, IntPtr.Zero,
                                 Win32NativeFileCreationDisposition.OpenAlways,
                                 fileAttributes, IntPtr.Zero);


            if (_handle.IsInvalid)
            {
                var lastWin32ErrorCode = Marshal.GetLastWin32Error();
                throw new IOException("Failed to open file storage of Win32MemoryMapPager for " + file,
                                      new Win32Exception(lastWin32ErrorCode));
            }

            _fileInfo = new FileInfo(file);

            var streamAccessType = access == Win32NativeFileAccess.GenericRead
                 ? FileAccess.Read
                 : FileAccess.ReadWrite;

            _fileStream = new FileStream(_handle, streamAccessType);

            _totalAllocationSize = _fileInfo.Length;

            if (access.HasFlag(Win32NativeFileAccess.GenericWrite) ||
                access.HasFlag(Win32NativeFileAccess.GenericAll) ||
                access.HasFlag(Win32NativeFileAccess.FILE_GENERIC_WRITE))
            {
                var fileLength = _fileStream.Length;
                if ((fileLength == 0) && initialFileSize.HasValue)
                {
                    fileLength = initialFileSize.Value;
                }

                if ((_fileStream.Length == 0) || (fileLength % AllocationGranularity != 0))
                {
                    fileLength = NearestSizeToAllocationGranularity(fileLength);

                    SetFileLength(_handle, fileLength);
                }
                _totalAllocationSize = fileLength;
            }


            NumberOfAllocatedPages = _totalAllocationSize / PageSize;

            SetPagerState(CreatePagerState());
        }