// Get everything ready to run. Only call this once, unlike Pin.
        //
        void Prepare()
        {
            if (this.currentState != State.Unprepared)
            {
                // An internal consistency check has failed. The indicates a bug in IO.Log's internal processing
                // Rather than proceeding with non-deterministic execution and risking the loss or corruption of
                // log records, we failfast the process.
                DiagnosticUtility.FailFast("Calling Prepare Twice");
            }

            // Box the result LSN.
            //
            ulong resultLsn = 0;

            this.boxedResultLsn = (object)(resultLsn);

            int paddingSize = 0;

            if (this.reservationCollection != null)
            {
                // Determine if we are writing from reservation.
                // Get the best matching reservation if so. Allocate padding
                // if necessary.
                //
                if (this.reservations == null)
                {
                    this.reservationSize = this.reservationCollection.GetMatchingReservation(this.totalRecordSize);
                    if (this.reservationSize < this.totalRecordSize)
                    {
                        // An internal consistency check has failed. The indicates a bug in IO.Log's internal processing
                        // Rather than proceeding with non-deterministic execution and risking the loss or corruption of
                        // log records, we failfast the process.
                        DiagnosticUtility.FailFast("Somehow got a smaller reservation");
                    }
                    if (this.reservationSize <= 0)
                    {
                        // An internal consistency check has failed. The indicates a bug in IO.Log's internal processing
                        // Rather than proceeding with non-deterministic execution and risking the loss or corruption of
                        // log records, we failfast the process.
                        DiagnosticUtility.FailFast("Reservation size must be bigger than zero");
                    }

                    paddingSize = checked ((int)(this.reservationSize -
                                                 this.totalRecordSize));
                }
                else
                {
                    // Otherwise, we are making new reservations
                    // (ReserveAndAppend). The reservations we make
                    // must be adjusted by the header size.
                    //
                    long[] adjustedReservations = new long[this.reservations.Length];
                    for (int i = 0; i < adjustedReservations.Length; i++)
                    {
                        adjustedReservations[i] = (this.reservations[i] +
                                                   LogLogRecordHeader.Size);
                    }
                    this.reservations        = adjustedReservations;
                    this.alignedReservations = (long[])this.reservations.Clone();
                }
            }

            // Allocate a new LogLogRecordHeader and set it up
            // correctly.
            //
            this.headerBits = new byte[LogLogRecordHeader.Size + paddingSize];
            LogLogRecordHeader header = new LogLogRecordHeader(this.headerBits);

            header.MajorVersion = LogLogRecordHeader.CurrentMajorVersion;
            header.MinorVersion = LogLogRecordHeader.CurrentMinorVersion;
            header.Padding      = (paddingSize != 0);
            if (paddingSize != 0)
            {
                LogLogRecordHeader.EncodePaddingSize(this.headerBits,
                                                     LogLogRecordHeader.Size,
                                                     paddingSize);
            }

            // Translate write flags to CLFS flags.
            //
            this.flags = 0;
            if ((this.recordAppendOptions & RecordAppendOptions.ForceAppend) != 0)
            {
                this.flags |= Const.CLFS_FLAG_FORCE_APPEND;
            }
            if ((this.recordAppendOptions & RecordAppendOptions.ForceFlush) != 0)
            {
                this.flags |= Const.CLFS_FLAG_FORCE_FLUSH;
            }
            if (this.reservationSize > 0)
            {
                this.flags |= Const.CLFS_FLAG_USE_RESERVATION;
            }

            this.currentState = State.Prepared;
        }
Ejemplo n.º 2
0
        // Get everything ready to run. Only call this once, unlike Pin.
        //
        void Prepare()
        {
            if (this.currentState != State.Unprepared)
            {
                // An internal consistency check has failed. The indicates a bug in IO.Log's internal processing
                // Rather than proceeding with non-deterministic execution and risking the loss or corruption of
                // log records, we failfast the process.
                DiagnosticUtility.FailFast("Calling Prepare Twice");
            }

            // Box the result LSN.
            //
            ulong resultLsn = 0;

            this.boxedResultLsn = (object)(resultLsn);

            // Determine if we are writing from reservation.
            // Get the best matching reservation if so. Allocate padding
            // if necessary.
            //
            int paddingSize = 0;

            if (this.reservationCollection != null)
            {
                this.reservationSize = this.reservationCollection.GetMatchingReservation(this.totalRecordSize);
                if (this.reservationSize < this.totalRecordSize)
                {
                    // An internal consistency check has failed. The indicates a bug in IO.Log's internal processing
                    // Rather than proceeding with non-deterministic execution and risking the loss or corruption of
                    // log records, we failfast the process.
                    DiagnosticUtility.FailFast("Somehow got a smaller reservation");
                }
                if (this.reservationSize <= 0)
                {
                    // An internal consistency check has failed. The indicates a bug in IO.Log's internal processing
                    // Rather than proceeding with non-deterministic execution and risking the loss or corruption of
                    // log records, we failfast the process.
                    DiagnosticUtility.FailFast("Reservation size must be bigger than zero");
                }

                paddingSize = checked ((int)(this.reservationSize -
                                             this.totalRecordSize));
                this.flags = Const.CLFS_FLAG_USE_RESERVATION;
            }

            // Allocate a new LogLogRecordHeader and set it up
            // correctly.
            //
            byte[]             headerBytes = new byte[LogLogRecordHeader.Size + paddingSize];
            LogLogRecordHeader header      = new LogLogRecordHeader(headerBytes);

            header.MajorVersion = LogLogRecordHeader.CurrentMajorVersion;
            header.MinorVersion = LogLogRecordHeader.CurrentMinorVersion;
            header.Padding      = (paddingSize != 0);
            if (paddingSize != 0)
            {
                LogLogRecordHeader.EncodePaddingSize(headerBytes,
                                                     LogLogRecordHeader.Size,
                                                     paddingSize);
            }

            // Now we write-gather here, since WriteLogRestartArea does
            // not support write-gather.
            //
            // (NOTE: totalRecordSize includes the size of the header,
            //        for consistency with reservations...)
            //
            long restartAreaSize = this.totalRecordSize + paddingSize;

            this.restartArea = new byte[restartAreaSize];
            restartAreaSize  = 0;

            Array.Copy(header.Bits,
                       0,
                       this.restartArea,
                       restartAreaSize,
                       header.Bits.Length);
            restartAreaSize += header.Bits.Length;

            for (int i = 0; i < this.data.Count; i++)
            {
                ArraySegment <byte> segment = this.data[i];

                Array.Copy(segment.Array,
                           segment.Offset,
                           this.restartArea,
                           restartAreaSize,
                           segment.Count);
                restartAreaSize += segment.Count;
            }

            if (restartAreaSize != this.restartArea.Length)
            {
                // An internal consistency check has failed. The indicates a bug in IO.Log's internal processing
                // Rather than proceeding with non-deterministic execution and risking the loss or corruption of
                // log records, we failfast the process.
                DiagnosticUtility.FailFast("Did not do restartArea gather correctly");
            }

            this.currentState = State.Prepared;
        }