Beispiel #1
0
        public int Claim(
            int termId,
            int termOffset,
            HeaderWriter header,
            int length,
            BufferClaim bufferClaim)
        {
            int          frameLength   = length + DataHeaderFlyweight.HEADER_LENGTH;
            int          alignedLength = BitUtil.Align(frameLength, FrameDescriptor.FRAME_ALIGNMENT);
            UnsafeBuffer termBuffer    = _termBuffer;
            int          termLength    = termBuffer.Capacity;

            int resultingOffset = termOffset + alignedLength;

            PutRawTailOrdered(termId, resultingOffset);

            if (resultingOffset > termLength)
            {
                resultingOffset = HandleEndOfLogCondition(termBuffer, termOffset, header, termLength, termId);
            }
            else
            {
                header.Write(termBuffer, termOffset, frameLength, termId);
                bufferClaim.Wrap(termBuffer, termOffset, frameLength);
            }

            return(resultingOffset);
        }
Beispiel #2
0
        public int AppendFragmentedMessage(HeaderWriter header, IDirectBuffer srcBuffer, int srcOffset, int length,
                                           int maxPayloadLength, ReservedValueSupplier reservedValueSupplier, int activeTermId)
        {
            int          numMaxPayloads   = length / maxPayloadLength;
            int          remainingPayload = length % maxPayloadLength;
            int          lastFrameLength  = remainingPayload > 0 ? BitUtil.Align(remainingPayload + DataHeaderFlyweight.HEADER_LENGTH, FrameDescriptor.FRAME_ALIGNMENT) : 0;
            int          requiredLength   = (numMaxPayloads * (maxPayloadLength + DataHeaderFlyweight.HEADER_LENGTH)) + lastFrameLength;
            long         rawTail          = GetAndAddRawTail(requiredLength);
            int          termId           = LogBufferDescriptor.TermId(rawTail);
            long         termOffset       = rawTail & 0xFFFFFFFFL;
            UnsafeBuffer termBuffer       = _termBuffer;
            int          termLength       = termBuffer.Capacity;

            CheckTerm(activeTermId, termId);

            long resultingOffset = termOffset + requiredLength;

            if (resultingOffset > termLength)
            {
                resultingOffset = HandleEndOfLogCondition(termBuffer, termOffset, header, termLength, termId);
            }
            else
            {
                int  frameOffset = (int)termOffset;
                byte flags       = FrameDescriptor.BEGIN_FRAG_FLAG;
                int  remaining   = length;

                do
                {
                    int bytesToWrite  = Math.Min(remaining, maxPayloadLength);
                    int frameLength   = bytesToWrite + DataHeaderFlyweight.HEADER_LENGTH;
                    int alignedLength = BitUtil.Align(frameLength, FrameDescriptor.FRAME_ALIGNMENT);

                    header.Write(termBuffer, frameOffset, frameLength, termId);
                    termBuffer.PutBytes(frameOffset + DataHeaderFlyweight.HEADER_LENGTH, srcBuffer,
                                        srcOffset + (length - remaining), bytesToWrite);

                    if (remaining <= maxPayloadLength)
                    {
                        flags |= FrameDescriptor.END_FRAG_FLAG;
                    }

                    FrameDescriptor.FrameFlags(termBuffer, frameOffset, flags);

                    if (null != reservedValueSupplier)
                    {
                        long reservedValue = reservedValueSupplier(termBuffer, frameOffset, frameLength);
                        termBuffer.PutLong(frameOffset + DataHeaderFlyweight.RESERVED_VALUE_OFFSET, reservedValue, ByteOrder.LittleEndian);
                    }

                    FrameDescriptor.FrameLengthOrdered(termBuffer, frameOffset, frameLength);

                    flags        = 0;
                    frameOffset += alignedLength;
                    remaining   -= bytesToWrite;
                } while (remaining > 0);
            }

            return((int)resultingOffset);
        }
Beispiel #3
0
        public long Claim(HeaderWriter header, int length, BufferClaim bufferClaim)
        {
            int  frameLength   = length + DataHeaderFlyweight.HEADER_LENGTH;
            int  alignedLength = BitUtil.Align(frameLength, FrameDescriptor.FRAME_ALIGNMENT);
            long rawTail       = GetAndAddRawTail(alignedLength);
            long termOffset    = rawTail & 0xFFFFFFFFL;

            UnsafeBuffer termBuffer = _termBuffer;
            int          termLength = termBuffer.Capacity;

            long resultingOffset = termOffset + alignedLength;

            if (resultingOffset > termLength)
            {
                resultingOffset = HandleEndOfLogCondition(termBuffer, termOffset, header, termLength, LogBufferDescriptor.TermId(rawTail));
            }
            else
            {
                int offset = (int)termOffset;
                header.Write(termBuffer, offset, frameLength, LogBufferDescriptor.TermId(rawTail));
                bufferClaim.Wrap(termBuffer, offset, frameLength);
            }

            return(resultingOffset);
        }
Beispiel #4
0
        public long AppendUnfragmentedMessage(HeaderWriter header, UnsafeBuffer srcBuffer, int srcOffset, int length, ReservedValueSupplier reservedValueSupplier)
#endif
        {
            int  frameLength   = length + DataHeaderFlyweight.HEADER_LENGTH;
            int  alignedLength = BitUtil.Align(frameLength, FrameDescriptor.FRAME_ALIGNMENT);
            long rawTail       = GetAndAddRawTail(alignedLength);
            long termOffset    = rawTail & 0xFFFFFFFFL;

            UnsafeBuffer termBuffer = _termBuffer;
            int          termLength = termBuffer.Capacity;

            long resultingOffset = termOffset + alignedLength;

            if (resultingOffset > termLength)
            {
                resultingOffset = HandleEndOfLogCondition(termBuffer, termOffset, header, termLength, LogBufferDescriptor.TermId(rawTail));
            }
            else
            {
                int offset = (int)termOffset;
                header.Write(termBuffer, offset, frameLength, LogBufferDescriptor.TermId(rawTail));
                termBuffer.PutBytes(offset + DataHeaderFlyweight.HEADER_LENGTH, srcBuffer, srcOffset, length);

                if (null != reservedValueSupplier)
                {
                    long reservedValue = reservedValueSupplier(termBuffer, offset, frameLength);
                    termBuffer.PutLong(offset + DataHeaderFlyweight.RESERVED_VALUE_OFFSET, reservedValue);
                }

                FrameDescriptor.FrameLengthOrdered(termBuffer, offset, frameLength);
            }

            return(resultingOffset);
        }
Beispiel #5
0
        /// <summary>
        /// Append an unfragmented message to the the term buffer.
        /// </summary>
        /// <param name="header">    for writing the default header. </param>
        /// <param name="srcBuffer"> containing the message. </param>
        /// <param name="srcOffset"> at which the message begins. </param>
        /// <param name="length">    of the message in the source buffer. </param>
        /// <returns> the resulting offset of the term after the append on success otherwise <seealso cref="#TRIPPED"/> or <seealso cref="#FAILED"/>
        /// packed with the termId if a padding record was inserted at the end. </returns>
        public virtual long AppendUnfragmentedMessage(HeaderWriter header, IDirectBuffer srcBuffer, int srcOffset, int length)
        {
            int  frameLength   = length + DataHeaderFlyweight.HEADER_LENGTH;
            int  alignedLength = BitUtil.Align(frameLength, FrameDescriptor.FRAME_ALIGNMENT);
            long rawTail       = GetAndAddRawTail(alignedLength);
            long termOffset    = rawTail & 0xFFFFFFFFL;

            IAtomicBuffer termBuffer = _termBuffer;
            int           termLength = termBuffer.Capacity;

            long resultingOffset = termOffset + alignedLength;

            if (resultingOffset > termLength)
            {
                resultingOffset = HandleEndOfLogCondition(termBuffer, termOffset, header, termLength, TermId(rawTail));
            }
            else
            {
                int offset = (int)termOffset;
                header.Write(termBuffer, offset, frameLength, TermId(rawTail));
                termBuffer.PutBytes(offset + DataHeaderFlyweight.HEADER_LENGTH, srcBuffer, srcOffset, length);
                FrameDescriptor.FrameLengthOrdered(termBuffer, offset, frameLength);
            }

            return(resultingOffset);
        }
Beispiel #6
0
        /// <summary>
        /// Append a fragmented message to the the term buffer.
        /// The message will be split up into fragments of MTU length minus header.
        /// </summary>
        /// <param name="header">           for writing the default header. </param>
        /// <param name="srcBuffer">        containing the message. </param>
        /// <param name="srcOffset">        at which the message begins. </param>
        /// <param name="length">           of the message in the source buffer. </param>
        /// <param name="maxPayloadLength"> that the message will be fragmented into. </param>
        /// <returns> the resulting offset of the term after the append on success otherwise <seealso cref="#TRIPPED"/> or <seealso cref="#FAILED"/>
        /// packed with the termId if a padding record was inserted at the end. </returns>
        public long AppendFragmentedMessage(HeaderWriter header, IDirectBuffer srcBuffer, int srcOffset, int length,
                                            int maxPayloadLength)
        {
            int numMaxPayloads   = length / maxPayloadLength;
            int remainingPayload = length % maxPayloadLength;
            int lastFrameLength  = remainingPayload > 0
                ? BitUtil.Align(remainingPayload + DataHeaderFlyweight.HEADER_LENGTH, FrameDescriptor.FRAME_ALIGNMENT)
                : 0;
            int requiredLength = (numMaxPayloads * (maxPayloadLength + DataHeaderFlyweight.HEADER_LENGTH)) +
                                 lastFrameLength;
            long rawTail    = GetAndAddRawTail(requiredLength);
            int  termId     = TermId(rawTail);
            long termOffset = rawTail & 0xFFFFFFFFL;

            IAtomicBuffer termBuffer = _termBuffer;
            int           termLength = termBuffer.Capacity;

            long resultingOffset = termOffset + requiredLength;

            if (resultingOffset > termLength)
            {
                resultingOffset = HandleEndOfLogCondition(termBuffer, termOffset, header, termLength, termId);
            }
            else
            {
                int  offset    = (int)termOffset;
                byte flags     = FrameDescriptor.BEGIN_FRAG_FLAG;
                int  remaining = length;
                do
                {
                    int bytesToWrite  = Math.Min(remaining, maxPayloadLength);
                    int frameLength   = bytesToWrite + DataHeaderFlyweight.HEADER_LENGTH;
                    int alignedLength = BitUtil.Align(frameLength, FrameDescriptor.FRAME_ALIGNMENT);

                    header.Write(termBuffer, offset, frameLength, termId);
                    termBuffer.PutBytes(offset + DataHeaderFlyweight.HEADER_LENGTH, srcBuffer,
                                        srcOffset + (length - remaining), bytesToWrite);

                    if (remaining <= maxPayloadLength)
                    {
                        flags |= FrameDescriptor.END_FRAG_FLAG;
                    }

                    FrameDescriptor.FrameFlags(termBuffer, offset, flags);
                    FrameDescriptor.FrameLengthOrdered(termBuffer, offset, frameLength);

                    flags      = 0;
                    offset    += alignedLength;
                    remaining -= bytesToWrite;
                } while (remaining > 0);
            }

            return(resultingOffset);
        }
Beispiel #7
0
        private long HandleEndOfLogCondition(UnsafeBuffer termBuffer, long termOffset, HeaderWriter header,
                                             int termLength, int termId)
        {
            if (termOffset < termLength)
            {
                int offset        = (int)termOffset;
                int paddingLength = termLength - offset;
                header.Write(termBuffer, offset, paddingLength, termId);
                FrameDescriptor.FrameType(termBuffer, offset, FrameDescriptor.PADDING_FRAME_TYPE);
                FrameDescriptor.FrameLengthOrdered(termBuffer, offset, paddingLength);
            }

            return(FAILED);
        }
Beispiel #8
0
        public int AppendUnfragmentedMessage(
            HeaderWriter header,
            DirectBufferVector[] vectors,
            int length,
            ReservedValueSupplier reservedValueSupplier,
            int activeTermId)
        {
            int          frameLength   = length + DataHeaderFlyweight.HEADER_LENGTH;
            int          alignedLength = BitUtil.Align(frameLength, FrameDescriptor.FRAME_ALIGNMENT);
            UnsafeBuffer termBuffer    = _termBuffer;
            int          termLength    = termBuffer.Capacity;

            long rawTail    = GetAndAddRawTail(alignedLength);
            int  termId     = LogBufferDescriptor.TermId(rawTail);
            long termOffset = rawTail & 0xFFFFFFFFL;


            CheckTerm(activeTermId, termId);

            long resultingOffset = termOffset + alignedLength;

            if (resultingOffset > termLength)
            {
                resultingOffset = HandleEndOfLogCondition(termBuffer, termOffset, header, termLength, termId);
            }
            else
            {
                int frameOffset = (int)termOffset;
                header.Write(termBuffer, frameOffset, frameLength, LogBufferDescriptor.TermId(rawTail));

                int offset = frameOffset + DataHeaderFlyweight.HEADER_LENGTH;

                foreach (var vector in vectors)
                {
                    termBuffer.PutBytes(offset, vector.buffer, vector.offset, vector.length);
                    offset += vector.length;
                }

                if (null != reservedValueSupplier)
                {
                    long reservedValue = reservedValueSupplier(termBuffer, frameOffset, frameLength);
                    termBuffer.PutLong(frameOffset + DataHeaderFlyweight.RESERVED_VALUE_OFFSET, reservedValue, ByteOrder.LittleEndian);
                }

                FrameDescriptor.FrameLengthOrdered(termBuffer, frameOffset, frameLength);
            }

            return((int)resultingOffset);
        }
Beispiel #9
0
        public int AppendUnfragmentedMessage(
            int termId,
            int termOffset,
            HeaderWriter header,
            DirectBufferVector[] vectors,
            int length,
            ReservedValueSupplier reservedValueSupplier)
#endif
        {
            int          frameLength   = length + DataHeaderFlyweight.HEADER_LENGTH;
            int          alignedLength = BitUtil.Align(frameLength, FrameDescriptor.FRAME_ALIGNMENT);
            UnsafeBuffer termBuffer    = _termBuffer;
            int          termLength    = termBuffer.Capacity;

            int resultingOffset = termOffset + alignedLength;

            PutRawTailOrdered(termId, resultingOffset);

            if (resultingOffset > termLength)
            {
                resultingOffset = HandleEndOfLogCondition(termBuffer, termOffset, header, termLength, termId);
            }
            else
            {
                header.Write(termBuffer, termOffset, frameLength, termId);

                var offset = termOffset + DataHeaderFlyweight.HEADER_LENGTH;

                foreach (var vector in vectors)
                {
                    termBuffer.PutBytes(offset, vector.buffer, vector.offset, vector.length);
                    offset += vector.length;
                }

                if (null != reservedValueSupplier)
                {
                    long reservedValue = reservedValueSupplier(termBuffer, termOffset, frameLength);
                    termBuffer.PutLong(termOffset + DataHeaderFlyweight.RESERVED_VALUE_OFFSET, reservedValue, ByteOrder.LittleEndian);
                }

                FrameDescriptor.FrameLengthOrdered(termBuffer, termOffset, frameLength);
            }

            return(resultingOffset);
        }
        /// <summary>
        /// Append an unfragmented message to the the term buffer.
        /// </summary>
        /// <param name="termId">                for the current term. </param>
        /// <param name="termOffset">            in the term at which to append. </param>
        /// <param name="header">                for writing the default header. </param>
        /// <param name="bufferOne">             containing the first part of the message. </param>
        /// <param name="offsetOne">             at which the first part of the message begins. </param>
        /// <param name="lengthOne">             of the first part of the message. </param>
        /// <param name="bufferTwo">             containing the second part of the message. </param>
        /// <param name="offsetTwo">             at which the second part of the message begins. </param>
        /// <param name="lengthTwo">             of the second part of the message. </param>
        /// <param name="reservedValueSupplier"> <seealso cref="ReservedValueSupplier"/> for the frame. </param>
        /// <returns> the resulting offset of the term after the append on success otherwise <seealso cref="FAILED"/>. </returns>
        public int AppendUnfragmentedMessage(
            int termId,
            int termOffset,
            HeaderWriter header,
            IDirectBuffer bufferOne,
            int offsetOne,
            int lengthOne,
            IDirectBuffer bufferTwo,
            int offsetTwo,
            int lengthTwo,
            ReservedValueSupplier reservedValueSupplier)
        {
            int          frameLength   = lengthOne + lengthTwo + DataHeaderFlyweight.HEADER_LENGTH;
            int          alignedLength = BitUtil.Align(frameLength, FrameDescriptor.FRAME_ALIGNMENT);
            UnsafeBuffer termBuffer    = _termBuffer;
            int          termLength    = termBuffer.Capacity;

            int resultingOffset = termOffset + alignedLength;

            PutRawTailOrdered(termId, resultingOffset);

            if (resultingOffset > termLength)
            {
                resultingOffset = HandleEndOfLogCondition(termBuffer, termOffset, header, termLength, termId);
            }
            else
            {
                header.Write(termBuffer, termOffset, frameLength, termId);
                termBuffer.PutBytes(termOffset + DataHeaderFlyweight.HEADER_LENGTH, bufferOne, offsetOne, lengthOne);
                termBuffer.PutBytes(termOffset + DataHeaderFlyweight.HEADER_LENGTH + lengthOne, bufferTwo, offsetTwo, lengthTwo);

                if (null != reservedValueSupplier)
                {
                    long reservedValue = reservedValueSupplier(termBuffer, termOffset, frameLength);
                    termBuffer.PutLong(termOffset + DataHeaderFlyweight.RESERVED_VALUE_OFFSET, reservedValue, ByteOrder.LittleEndian);
                }

                FrameDescriptor.FrameLengthOrdered(termBuffer, termOffset, frameLength);
            }

            return(resultingOffset);
        }
Beispiel #11
0
        private long HandleEndOfLogCondition(UnsafeBuffer termBuffer, long termOffset, HeaderWriter header,
                                             int termLength, int termId)
        {
            int resultingOffset = FAILED;

            if (termOffset <= termLength)
            {
                resultingOffset = TRIPPED;

                if (termOffset < termLength)
                {
                    int offset        = (int)termOffset;
                    int paddingLength = termLength - offset;
                    header.Write(termBuffer, offset, paddingLength, termId);
                    FrameDescriptor.FrameType(termBuffer, offset, FrameDescriptor.PADDING_FRAME_TYPE);
                    FrameDescriptor.FrameLengthOrdered(termBuffer, offset, paddingLength);
                }
            }

            return(LogBufferDescriptor.PackTail(termId, resultingOffset));
        }
Beispiel #12
0
        public int AppendFragmentedMessage(
            int termId,
            int termOffset,
            HeaderWriter header,
            DirectBufferVector[] vectors,
            int length,
            int maxPayloadLength,
            ReservedValueSupplier reservedValueSupplier)
        {
            int numMaxPayloads   = length / maxPayloadLength;
            int remainingPayload = length % maxPayloadLength;
            int lastFrameLength  = remainingPayload > 0
                ? BitUtil.Align(remainingPayload + DataHeaderFlyweight.HEADER_LENGTH, FrameDescriptor.FRAME_ALIGNMENT)
                : 0;
            int requiredLength = (numMaxPayloads * (maxPayloadLength + DataHeaderFlyweight.HEADER_LENGTH)) +
                                 lastFrameLength;
            UnsafeBuffer termBuffer = _termBuffer;
            int          termLength = termBuffer.Capacity;

            int resultingOffset = termOffset + requiredLength;

            PutRawTailOrdered(termId, resultingOffset);

            if (resultingOffset > termLength)
            {
                resultingOffset = HandleEndOfLogCondition(termBuffer, termOffset, header, termLength, termId);
            }
            else
            {
                int  frameOffset  = termOffset;
                byte flags        = FrameDescriptor.BEGIN_FRAG_FLAG;
                int  remaining    = length;
                int  vectorIndex  = 0;
                int  vectorOffset = 0;

                do
                {
                    int bytesToWrite  = Math.Min(remaining, maxPayloadLength);
                    int frameLength   = bytesToWrite + DataHeaderFlyweight.HEADER_LENGTH;
                    int alignedLength = BitUtil.Align(frameLength, FrameDescriptor.FRAME_ALIGNMENT);

                    header.Write(termBuffer, frameOffset, frameLength, termId);

                    int bytesWritten  = 0;
                    int payloadOffset = frameOffset + DataHeaderFlyweight.HEADER_LENGTH;

                    do
                    {
                        var vector          = vectors[vectorIndex];
                        int vectorRemaining = vector.length - vectorOffset;
                        int numBytes        = Math.Min(bytesToWrite - bytesWritten, vectorRemaining);

                        termBuffer.PutBytes(payloadOffset, vector.buffer, vector.offset + vectorOffset, numBytes);

                        bytesWritten  += numBytes;
                        payloadOffset += numBytes;
                        vectorOffset  += numBytes;

                        if (vectorRemaining <= numBytes)
                        {
                            vectorIndex++;
                            vectorOffset = 0;
                        }
                    } while (bytesWritten < bytesToWrite);

                    if (remaining <= maxPayloadLength)
                    {
                        flags |= FrameDescriptor.END_FRAG_FLAG;
                    }

                    FrameDescriptor.FrameFlags(termBuffer, frameOffset, flags);

                    if (null != reservedValueSupplier)
                    {
                        long reservedValue = reservedValueSupplier(termBuffer, frameOffset, frameLength);
                        termBuffer.PutLong(frameOffset + DataHeaderFlyweight.RESERVED_VALUE_OFFSET, reservedValue, ByteOrder.LittleEndian);
                    }

                    FrameDescriptor.FrameLengthOrdered(termBuffer, frameOffset, frameLength);

                    flags        = 0;
                    frameOffset += alignedLength;
                    remaining   -= bytesToWrite;
                } while (remaining > 0);
            }

            return(resultingOffset);
        }
Beispiel #13
0
        /// <summary>
        /// Claim length of a the term buffer for writing in the message with zero copy semantics.
        /// </summary>
        /// <param name="header">      for writing the default header. </param>
        /// <param name="length">      of the message to be written. </param>
        /// <param name="bufferClaim"> to be updated with the claimed region. </param>
        /// <returns> the resulting offset of the term after the append on success otherwise <seealso cref="#TRIPPED"/> or <seealso cref="#FAILED"/>
        /// packed with the termId if a padding record was inserted at the end. </returns>
        public long Claim(HeaderWriter header, int length, BufferClaim bufferClaim)
        {
            int frameLength = length + DataHeaderFlyweight.HEADER_LENGTH;
            int alignedLength = BitUtil.Align(frameLength, FrameDescriptor.FRAME_ALIGNMENT);
            long rawTail = GetAndAddRawTail(alignedLength);
            long termOffset = rawTail & 0xFFFFFFFFL;

            IAtomicBuffer termBuffer = _termBuffer;
            int termLength = termBuffer.Capacity;

            long resultingOffset = termOffset + alignedLength;
            if (resultingOffset > termLength)
            {
                resultingOffset = HandleEndOfLogCondition(termBuffer, termOffset, header, termLength, TermId(rawTail));
            }
            else
            {
                int offset = (int) termOffset;
                header.Write(termBuffer, offset, frameLength, TermId(rawTail));
                bufferClaim.Wrap(termBuffer, offset, frameLength);
            }

            return resultingOffset;
        }
Beispiel #14
0
        private long HandleEndOfLogCondition(IAtomicBuffer termBuffer, long termOffset, HeaderWriter header,
            int termLength, int termId)
        {
            int resultingOffset = FAILED;

            if (termOffset <= termLength)
            {
                resultingOffset = TRIPPED;

                if (termOffset < termLength)
                {
                    int offset = (int) termOffset;
                    int paddingLength = termLength - offset;
                    header.Write(termBuffer, offset, paddingLength, termId);
                    FrameDescriptor.FrameType(termBuffer, offset, FrameDescriptor.PADDING_FRAME_TYPE);
                    FrameDescriptor.FrameLengthOrdered(termBuffer, offset, paddingLength);
                }
            }

            return Pack(termId, resultingOffset);
        }
Beispiel #15
0
        /// <summary>
        /// Append a fragmented message to the the term buffer.
        /// The message will be split up into fragments of MTU length minus header.
        /// </summary>
        /// <param name="header">           for writing the default header. </param>
        /// <param name="srcBuffer">        containing the message. </param>
        /// <param name="srcOffset">        at which the message begins. </param>
        /// <param name="length">           of the message in the source buffer. </param>
        /// <param name="maxPayloadLength"> that the message will be fragmented into. </param>
        /// /// <param name="reservedValueSupplier"><see cref="ReservedValueSupplier"/> for the frame</param>
        /// <returns> the resulting offset of the term after the append on success otherwise <seealso cref="#TRIPPED"/> or <seealso cref="#FAILED"/>
        /// packed with the termId if a padding record was inserted at the end. </returns>
        public long AppendFragmentedMessage(HeaderWriter header, IDirectBuffer srcBuffer, int srcOffset, int length,
            int maxPayloadLength, ReservedValueSupplier reservedValueSupplier)
        {
            int numMaxPayloads = length/maxPayloadLength;
            int remainingPayload = length%maxPayloadLength;
            int lastFrameLength = remainingPayload > 0
                ? BitUtil.Align(remainingPayload + DataHeaderFlyweight.HEADER_LENGTH, FrameDescriptor.FRAME_ALIGNMENT)
                : 0;
            int requiredLength = (numMaxPayloads*(maxPayloadLength + DataHeaderFlyweight.HEADER_LENGTH)) +
                                 lastFrameLength;
            long rawTail = GetAndAddRawTail(requiredLength);
            int termId = TermId(rawTail);
            long termOffset = rawTail & 0xFFFFFFFFL;

            IAtomicBuffer termBuffer = _termBuffer;
            int termLength = termBuffer.Capacity;

            long resultingOffset = termOffset + requiredLength;
            if (resultingOffset > termLength)
            {
                resultingOffset = HandleEndOfLogCondition(termBuffer, termOffset, header, termLength, termId);
            }
            else
            {
                int offset = (int) termOffset;
                byte flags = FrameDescriptor.BEGIN_FRAG_FLAG;
                int remaining = length;
                do
                {
                    int bytesToWrite = Math.Min(remaining, maxPayloadLength);
                    int frameLength = bytesToWrite + DataHeaderFlyweight.HEADER_LENGTH;
                    int alignedLength = BitUtil.Align(frameLength, FrameDescriptor.FRAME_ALIGNMENT);

                    header.Write(termBuffer, offset, frameLength, termId);
                    termBuffer.PutBytes(offset + DataHeaderFlyweight.HEADER_LENGTH, srcBuffer,
                        srcOffset + (length - remaining), bytesToWrite);

                    if (remaining <= maxPayloadLength)
                    {
                        flags |= FrameDescriptor.END_FRAG_FLAG;
                    }

                    FrameDescriptor.FrameFlags(termBuffer, offset, flags);

                    if (null != reservedValueSupplier)
                    {
                        long reservedValue = reservedValueSupplier(termBuffer, offset, frameLength);
                        termBuffer.PutLong(offset + DataHeaderFlyweight.RESERVED_VALUE_OFFSET, reservedValue);
                    }

                    FrameDescriptor.FrameLengthOrdered(termBuffer, offset, frameLength);

                    flags = 0;
                    offset += alignedLength;
                    remaining -= bytesToWrite;
                } while (remaining > 0);
            }

            return resultingOffset;
        }
Beispiel #16
0
        /// <summary>
        /// Append an unfragmented message to the the term buffer.
        /// </summary>
        /// <param name="header">    for writing the default header. </param>
        /// <param name="srcBuffer"> containing the message. </param>
        /// <param name="srcOffset"> at which the message begins. </param>
        /// <param name="length">    of the message in the source buffer. </param>
        /// <param name="reservedValueSupplier"><see cref="ReservedValueSupplier"/> for the frame</param>
        /// <returns> the resulting offset of the term after the append on success otherwise <seealso cref="TRIPPED"/> or <seealso cref="FAILED"/>
        /// packed with the termId if a padding record was inserted at the end. </returns>
        public virtual long AppendUnfragmentedMessage(HeaderWriter header, IDirectBuffer srcBuffer, int srcOffset, int length, ReservedValueSupplier reservedValueSupplier)
        {
            int frameLength = length + DataHeaderFlyweight.HEADER_LENGTH;
            int alignedLength = BitUtil.Align(frameLength, FrameDescriptor.FRAME_ALIGNMENT);
            long rawTail = GetAndAddRawTail(alignedLength);
            long termOffset = rawTail & 0xFFFFFFFFL;

            IAtomicBuffer termBuffer = _termBuffer;
            int termLength = termBuffer.Capacity;

            long resultingOffset = termOffset + alignedLength;
            if (resultingOffset > termLength)
            {
                resultingOffset = HandleEndOfLogCondition(termBuffer, termOffset, header, termLength, TermId(rawTail));
            }
            else
            {
                int offset = (int) termOffset;
                header.Write(termBuffer, offset, frameLength, TermId(rawTail));
                termBuffer.PutBytes(offset + DataHeaderFlyweight.HEADER_LENGTH, srcBuffer, srcOffset, length);

                if (null != reservedValueSupplier)
                {
                    long reservedValue = reservedValueSupplier(termBuffer, offset, frameLength);
                    termBuffer.PutLong(offset + DataHeaderFlyweight.RESERVED_VALUE_OFFSET, reservedValue);
                }

                FrameDescriptor.FrameLengthOrdered(termBuffer, offset, frameLength);
            }

            return resultingOffset;
        }