Beispiel #1
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 #2
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 #3
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);
        }