Esempio n. 1
0
        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();
            }
        }
Esempio n. 2
0
        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);
                }
            }
Esempio n. 4
0
            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);
                }
            }
Esempio n. 5
0
        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();
            }
        }
Esempio n. 6
0
        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();
        }
Esempio n. 7
0
        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);
                }
            }
Esempio n. 9
0
        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);
            }
        }
Esempio n. 10
0
        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;
        }