Esempio n. 1
0
        private void WriteFile(long position, byte *p, int numberOf4Kb)
        {
            position *= 4 * Constants.Size.Kilobyte;
            _nativeOverlapped->OffsetLow   = (int)(position & 0xffffffff);
            _nativeOverlapped->OffsetHigh  = (int)(position >> 32);
            _nativeOverlapped->EventHandle = IntPtr.Zero;

            Debug.Assert(_options.IoMetrics != null);

            bool writeSuccess;
            var  nNumberOfBytesToWrite = numberOf4Kb * (4 * Constants.Size.Kilobyte);

            using (var metrics = _options.IoMetrics.MeterIoRate(_filename.FullPath, IoMetrics.MeterType.JournalWrite, nNumberOfBytesToWrite))
            {
                int written;
                writeSuccess = Win32NativeFileMethods.WriteFile(_handle, p, nNumberOfBytesToWrite,
                                                                out written,
                                                                _nativeOverlapped);

                metrics.SetFileSize(NumberOfAllocated4Kb * (4 * Constants.Size.Kilobyte));
            }

            if (writeSuccess == false)
            {
                throw new IOException("Could not write to journal " + _filename,
                                      new Win32Exception(Marshal.GetLastWin32Error()));
            }
        }
Esempio n. 2
0
        private void WriteFile(long position, byte *p, int numberOfPages)
        {
            _nativeOverlapped->OffsetLow   = (int)(position & 0xffffffff);
            _nativeOverlapped->OffsetHigh  = (int)(position >> 32);
            _nativeOverlapped->EventHandle = IntPtr.Zero;

            Debug.Assert(_options.IoMetrics != null);

            bool writeSuccess;
            var  nNumberOfBytesToWrite = numberOfPages * _options.PageSize;

            using (_options.IoMetrics.MeterIoRate(_filename, IoMetrics.MeterType.JournalWrite, nNumberOfBytesToWrite))
            {
                int written;
                writeSuccess = Win32NativeFileMethods.WriteFile(_handle, p, nNumberOfBytesToWrite,
                                                                out written,
                                                                _nativeOverlapped);
            }

            if (writeSuccess == false)
            {
                throw new IOException("Could not write to journal " + _filename,
                                      new Win32Exception(Marshal.GetLastWin32Error()));
            }
        }
        public void WriteBuffer(long position, byte *srcPointer, int sizeToWrite)
        {
            if (Disposed)
            {
                throw new ObjectDisposedException("Win32JournalWriter");
            }

            int written;

            _nativeOverlapped->OffsetLow   = (int)(position & 0xffffffff);
            _nativeOverlapped->OffsetHigh  = (int)(position >> 32);
            _nativeOverlapped->EventHandle = IntPtr.Zero;


            var sp = Stopwatch.StartNew();
            var operationCompleted = Win32NativeFileMethods.WriteFile(_handle, srcPointer, sizeToWrite, out written, _nativeOverlapped);

            uint lpNumberOfBytesWritten;

            if (operationCompleted)
            {
                if (Win32NativeFileMethods.GetOverlappedResult(_handle, _nativeOverlapped, out lpNumberOfBytesWritten, true) == false)
                {
                    throw new VoronUnrecoverableErrorException("Could not write lazy buffer to journal " + _filename, new Win32Exception(Marshal.GetLastWin32Error()));
                }
                // TODO : Measure IO times (RavenDB-4659) - Wrote {sizeToWrite/1024:#,#} kb in {sp.ElapsedMilliseconds:#,#} ms
                return;
            }

            switch (Marshal.GetLastWin32Error())
            {
            case Win32NativeFileMethods.ErrorSuccess:
            case Win32NativeFileMethods.ErrorIOPending:
                if (Win32NativeFileMethods.GetOverlappedResult(_handle, _nativeOverlapped, out lpNumberOfBytesWritten, true) == false)
                {
                    throw new VoronUnrecoverableErrorException("Could not write lazy buffer to journal " + _filename, new Win32Exception(Marshal.GetLastWin32Error()));
                }
                // TODO : Measure IO times (RavenDB-4659) - Wrote  {sizeToWrite / 1024:#,#} kb in {sp.ElapsedMilliseconds:#,#} ms
                break;

            default:
                throw new VoronUnrecoverableErrorException("Could not write lazy buffer to journal " + _filename, new Win32Exception(Marshal.GetLastWin32Error()));
            }
        }
Esempio n. 4
0
 public static unsafe void WriteFileHeader(FileHeader *header, string path)
 {
     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 (Win32NativeFileMethods.WriteFile(fs.SafeFileHandle, ptr, remaining, out read, null) == false)
             {
                 throw new Win32Exception();
             }
             ptr       += read;
             remaining -= read;
         }
         Win32NativeFileMethods.FlushFileBuffers(fs.SafeFileHandle);
     }
 }
Esempio n. 5
0
 public static unsafe void WriteFileHeader(FileHeader *header, VoronPathSetting path)
 {
     using (var fs = SafeFileStream.Create(path.FullPath, FileMode.Create, FileAccess.ReadWrite, FileShare.Read, 4096, FileOptions.None))
     {
         var ptr       = (byte *)header;
         int remaining = sizeof(FileHeader);
         while (remaining > 0)
         {
             int written;
             if (Win32NativeFileMethods.WriteFile(fs.SafeFileHandle, ptr, remaining, out written, null) == false)
             {
                 throw new Win32Exception(Marshal.GetLastWin32Error(), "Failed to write to file " + path);
             }
             ptr       += written;
             remaining -= written;
         }
         if (Win32NativeFileMethods.FlushFileBuffers(fs.SafeFileHandle) == false)
         {
             throw new Win32Exception(Marshal.GetLastWin32Error(), "Failed to Flush File Buffers (sync) of file " + path);
         }
     }
 }
Esempio n. 6
0
        private void HandleWriteError(long position, byte *p, int numberOf4Kb)
        {
            var errorCode = Marshal.GetLastWin32Error();

            if (errorCode != ERROR_WORKING_SET_QUOTA)
            {
                ThrowOnWriteFileFailure(errorCode);
            }

            // this error can happen under low memory conditions, instead of trying to write the whole thing in a single shot
            // we'll write it in 4KB increments. This is likely to be much slower, but failing here will fail the entire DB
            for (int i = 0; i < numberOf4Kb; i++)
            {
                SetOverlappedPosition(position + i);
                var writeSuccess = Win32NativeFileMethods.WriteFile(_handle, p + (i * (4 * Constants.Size.Kilobyte)), (4 * Constants.Size.Kilobyte),
                                                                    out var written,
                                                                    _nativeOverlapped);

                if (writeSuccess == false)
                {
                    ThrowOnWriteFileFailure(Marshal.GetLastWin32Error());
                }
            }
        }
Esempio n. 7
0
        private void WriteFile(long position, byte *p, int numberOf4Kb)
        {
            Debug.Assert(_options.IoMetrics != null);

            SetOverlappedPosition(position);

            bool writeSuccess;
            var  nNumberOfBytesToWrite = numberOf4Kb * (4 * Constants.Size.Kilobyte);

            using (var metrics = _options.IoMetrics.MeterIoRate(_filename.FullPath, IoMetrics.MeterType.JournalWrite, nNumberOfBytesToWrite))
            {
                int written;
                writeSuccess = Win32NativeFileMethods.WriteFile(_handle, p, nNumberOfBytesToWrite,
                                                                out written,
                                                                _nativeOverlapped);

                if (writeSuccess == false)
                {
                    HandleWriteError(position, p, numberOf4Kb);
                }

                metrics.SetFileSize(NumberOfAllocated4Kb * (4 * Constants.Size.Kilobyte));
            }
        }