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();
        }
		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();
		}
Пример #3
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());
        }
Пример #4
0
        public Win32MemoryMapPager(StorageEnvironmentOptions options, string file,
                                   long?initialFileSize = null,
                                   Win32NativeFileAttributes fileAttributes = Win32NativeFileAttributes.Normal,
                                   Win32NativeFileAccess access             = Win32NativeFileAccess.GenericRead | Win32NativeFileAccess.GenericWrite,
                                   bool usePageProtection = false)
            : base(options, usePageProtection)
        {
            SYSTEM_INFO systemInfo;

            GetSystemInfo(out systemInfo);
            FileName = file;
            _logger  = LoggingSource.Instance.GetLogger <StorageEnvironment>($"Pager-{file}");
            AllocationGranularity = systemInfo.allocationGranularity;
            _access          = access;
            _copyOnWriteMode = Options.CopyOnWriteMode && FileName.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;
            }

            _handle = Win32NativeFileMethods.CreateFile(file, 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 Win32MemoryMapPager for " + file,
                                      new Win32Exception(lastWin32ErrorCode));
            }

            _fileInfo = new FileInfo(file);
            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 = 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;
            SetPagerState(CreatePagerState());
        }