public FilePager(string file) { _fileInfo = new FileInfo(file); var noData = _fileInfo.Exists == false || _fileInfo.Length == 0; _safeFileHandle = NativeFileMethods.CreateFile(file, NativeFileAccess.GenericRead | NativeFileAccess.GenericWrite, NativeFileShare.Read, IntPtr.Zero, NativeFileCreationDisposition.OpenAlways, NativeFileAttributes.Write_Through | NativeFileAttributes.NoBuffering, IntPtr.Zero); if (_safeFileHandle.IsInvalid) { throw new Win32Exception(); } _fileStream = new FileStream(_safeFileHandle, FileAccess.ReadWrite); if (noData) { NumberOfAllocatedPages = 0; } else { NumberOfAllocatedPages = _fileInfo.Length / PageSize; PagerState.Release(); PagerState = CreateNewPagerState(); } }
public override void AllocateMorePages(Transaction tx, long newLength) { if (newLength < _fileStream.Length) { throw new ArgumentException("Cannot set the legnth to less than the current length"); } if (newLength == _fileStream.Length) { return; } // need to allocate memory again NativeFileMethods.SetFileLength(_safeFileHandle, newLength); Debug.Assert(_fileStream.Length == newLength); PagerState.Release(); // when the last transaction using this is over, will dispose it PagerState newPager = CreateNewPagerState(); if (tx != null) // we only pass null during startup, and we don't need it there { newPager.AddRef(); // one for the current transaction tx.AddPagerState(newPager); } PagerState = newPager; NumberOfAllocatedPages = newLength / PageSize; }
public unsafe override bool ReadHeader(string filename, FileHeader *header) { var path = Path.Combine(_basePath, filename); if (File.Exists(path) == false) { return(false); } using (var fs = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) { if (fs.Length != sizeof(FileHeader)) { return(false); // wrong file size } var ptr = (byte *)header; int remaining = sizeof(FileHeader); while (remaining > 0) { int read; if (NativeFileMethods.ReadFile(fs.SafeFileHandle, ptr, remaining, out read, null) == false) { throw new Win32Exception(); } if (read == 0) { return(false); // we should be reading _something_ here, if we can't, then it is an error and we assume corruption } ptr += read; remaining -= read; } return(true); } }
public unsafe override bool ReadHeader(string filename, FileHeader *header) { var path = Path.Combine(_basePath, filename); if (File.Exists(path) == false) { return(false); } using (var fs = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) { var ptr = (byte *)header; int remaining = sizeof(FileHeader); while (remaining > 0) { int read; if (NativeFileMethods.ReadFile(fs.SafeFileHandle, ptr, remaining, out read, null) == false) { throw new Win32Exception(); } ptr += read; remaining -= read; } return(true); } }
public Win32MemoryMapPager(string file, NativeFileAttributes options = NativeFileAttributes.Normal, NativeFileAccess access = NativeFileAccess.GenericRead | NativeFileAccess.GenericWrite) { _access = access; _fileInfo = new FileInfo(file); bool noData = _fileInfo.Exists == false || _fileInfo.Length == 0; _handle = NativeFileMethods.CreateFile(file, access, NativeFileShare.Read | NativeFileShare.Write | NativeFileShare.Delete, IntPtr.Zero, NativeFileCreationDisposition.OpenAlways, options, IntPtr.Zero); if (_handle.IsInvalid) { int lastWin32ErrorCode = Marshal.GetLastWin32Error(); throw new IOException("Failed to open file storage of Win32MemoryMapPager", new Win32Exception(lastWin32ErrorCode)); } _fileStream = new FileStream(_handle, FileAccess.ReadWrite); if (noData) { NumberOfAllocatedPages = 0; } else { NumberOfAllocatedPages = _fileInfo.Length / PageSize; PagerState.Release(); PagerState = CreateNewPagerState(); } }
public Win32MemoryMapPager(string file, long?initialFileSize = null, NativeFileAttributes options = NativeFileAttributes.Normal, NativeFileAccess access = NativeFileAccess.GenericRead | NativeFileAccess.GenericWrite) { NativeMethods.SYSTEM_INFO systemInfo; NativeMethods.GetSystemInfo(out systemInfo); AllocationGranularity = systemInfo.allocationGranularity; _access = access; _memoryMappedFileAccess = _access == NativeFileAccess.GenericRead ? MemoryMappedFileAccess.Read : MemoryMappedFileAccess.ReadWrite; _handle = NativeFileMethods.CreateFile(file, access, NativeFileShare.Read | NativeFileShare.Write | NativeFileShare.Delete, IntPtr.Zero, NativeFileCreationDisposition.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 == NativeFileAccess.GenericRead ? FileAccess.Read : FileAccess.ReadWrite; _fileStream = new FileStream(_handle, streamAccessType); _totalAllocationSize = _fileInfo.Length; if (_access.HasFlag(NativeFileAccess.GenericWrite) || _access.HasFlag(NativeFileAccess.GenericAll) || _access.HasFlag(NativeFileAccess.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); _fileStream.SetLength(fileLength); } _totalAllocationSize = fileLength; } NumberOfAllocatedPages = _totalAllocationSize / PageSize; PagerState.Release(); PagerState = CreatePagerState(); }
public bool Read(long pageNumber, byte *buffer, int count) { if (_readHandle == null) { _readHandle = NativeFileMethods.CreateFile(_filename, NativeFileAccess.GenericRead, NativeFileShare.Write | NativeFileShare.Read | NativeFileShare.Delete, IntPtr.Zero, NativeFileCreationDisposition.OpenExisting, NativeFileAttributes.Normal, IntPtr.Zero); } long position = pageNumber * AbstractPager.PageSize; var overlapped = new Overlapped((int)(position & 0xffffffff), (int)(position >> 32), IntPtr.Zero, null); NativeOverlapped *nativeOverlapped = overlapped.Pack(null, null); try { while (count > 0) { int read; if (NativeFileMethods.ReadFile(_readHandle, buffer, count, out read, nativeOverlapped) == false) { int lastWin32Error = Marshal.GetLastWin32Error(); if (lastWin32Error == ErrorHandleEof) { return(false); } throw new Win32Exception(lastWin32Error); } count -= read; buffer += read; } return(true); } finally { Overlapped.Free(nativeOverlapped); } }
public override unsafe void WriteHeader(string filename, FileHeader *header) { var path = Path.Combine(_basePath, filename); using (var fs = new FileStream(path, FileMode.Create, FileAccess.ReadWrite, FileShare.Read)) { var ptr = (byte *)header; int remaining = sizeof(FileHeader); while (remaining > 0) { int read; if (NativeFileMethods.WriteFile(fs.SafeFileHandle, ptr, remaining, out read, null) == false) { throw new Win32Exception(); } ptr += read; remaining -= read; } NativeFileMethods.FlushFileBuffers(fs.SafeFileHandle); } }
public override int WriteDirect(Page start, long pagePosition, int pagesToWrite) { if (_fileInfo.Extension == ".voron" && pagePosition > 1) { } var position = pagePosition * PageSize; var toWrite = pagesToWrite * PageSize; var overlapped = new Overlapped() { OffsetLow = (int)(position & 0xffffffff), OffsetHigh = (int)(position >> 32), }; var nativeOverlapped = overlapped.Pack(null, null); try { var startWrite = start.Base; while (toWrite != 0) { int written; if (NativeFileMethods.WriteFile(_safeFileHandle, startWrite, toWrite, out written, nativeOverlapped) == false) { throw new Win32Exception(); } toWrite -= written; startWrite += written; } return(toWrite); } finally { Overlapped.Unpack(nativeOverlapped); Overlapped.Free(nativeOverlapped); } }
public Win32FileJournalWriter(string filename, long journalSize) { _filename = filename; _handle = NativeFileMethods.CreateFile(filename, NativeFileAccess.GenericWrite, NativeFileShare.Read, IntPtr.Zero, NativeFileCreationDisposition.OpenAlways, NativeFileAttributes.Write_Through | NativeFileAttributes.NoBuffering | NativeFileAttributes.Overlapped, IntPtr.Zero); if (_handle.IsInvalid) { throw new Win32Exception(); } NativeFileMethods.SetFileLength(_handle, journalSize); NumberOfAllocatedPages = journalSize / AbstractPager.PageSize; _manualResetEvent = new ManualResetEvent(false); _nativeOverlapped = (NativeOverlapped *)Marshal.AllocHGlobal(sizeof(NativeOverlapped)); _nativeOverlapped->InternalLow = IntPtr.Zero; _nativeOverlapped->InternalHigh = IntPtr.Zero; }