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); }
/// <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); }
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); }