Exemplo n.º 1
0
        public void WriteGather(long position, IntPtr[] pages)
        {
            if (Disposed)
            {
                throw new ObjectDisposedException("Win32JournalWriter");
            }

            EnsureSegmentsSize(pages);


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

            for (int i = 0; i < pages.Length; i++)
            {
                if (IntPtr.Size == 4)
                {
                    _segments[i].Alignment = (ulong)pages[i];
                }

                else
                {
                    _segments[i].Buffer = pages[i];
                }
            }
            _segments[pages.Length].Alignment = 0; // null terminating

            var operationCompleted = Win32NativeFileMethods.WriteFileGather(_handle, _segments, (uint)pages.Length * 4096, IntPtr.Zero, _nativeOverlapped);

            uint lpNumberOfBytesWritten;

            if (operationCompleted)
            {
                if (Win32NativeFileMethods.GetOverlappedResult(_handle, _nativeOverlapped, out lpNumberOfBytesWritten, true) == false)
                {
                    throw new VoronUnrecoverableErrorException("Could not write to journal " + _filename, new Win32Exception(Marshal.GetLastWin32Error()));
                }
                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 to journal " + _filename, new Win32Exception(Marshal.GetLastWin32Error()));
                }
                break;

            default:
                throw new VoronUnrecoverableErrorException("Could not write to journal " + _filename, new Win32Exception(Marshal.GetLastWin32Error()));
            }
        }
        public void WriteGather(long position, IntPtr[] pages)
        {
            if (Disposed)
            {
                throw new ObjectDisposedException("Win32JournalWriter");
            }

            var physicalPages = EnsureSegmentsSize(pages);

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

            PreparePagesToWrite(pages);
            var sp = Stopwatch.StartNew();
            // WriteFileGather will only be able to write x pages of size GetSystemInfo().dwPageSize. Usually that is 4096 (4kb). If you are
            // having trouble with this method, ensure that this value havent changed for your environment.
            var operationCompleted = Win32NativeFileMethods.WriteFileGather(_handle, _segments, (uint)(physicalPages * PhysicalPageSize), IntPtr.Zero, _nativeOverlapped);

            uint lpNumberOfBytesWritten;
            var  sizeToWrite = physicalPages * PhysicalPageSize;

            if (operationCompleted)
            {
                if (Win32NativeFileMethods.GetOverlappedResult(_handle, _nativeOverlapped, out lpNumberOfBytesWritten, true) == false)
                {
                    throw new VoronUnrecoverableErrorException("Could not write 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 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 to journal " + _filename, new Win32Exception(Marshal.GetLastWin32Error()));
            }
        }