internal Publication(ClientConductor clientConductor, string channel, int streamId, int sessionId, IReadablePosition positionLimit, LogBuffers logBuffers, long registrationId) { var buffers = logBuffers.AtomicBuffers(); var logMetaDataBuffer = buffers[LogBufferDescriptor.LOG_META_DATA_SECTION_INDEX]; for (var i = 0; i < LogBufferDescriptor.PARTITION_COUNT; i++) { _termAppenders[i] = new TermAppender(buffers[i], buffers[i + LogBufferDescriptor.PARTITION_COUNT]); } var termLength = logBuffers.TermLength(); _maxPayloadLength = LogBufferDescriptor.MtuLength(logMetaDataBuffer) - DataHeaderFlyweight.HEADER_LENGTH; MaxMessageLength = FrameDescriptor.ComputeMaxMessageLength(termLength); _clientConductor = clientConductor; Channel = channel; StreamId = streamId; SessionId = sessionId; InitialTermId = LogBufferDescriptor.InitialTermId(logMetaDataBuffer); _logMetaDataBuffer = logMetaDataBuffer; RegistrationId = registrationId; _positionLimit = positionLimit; _logBuffers = logBuffers; _positionBitsToShift = IntUtil.NumberOfTrailingZeros(termLength); _headerWriter = new HeaderWriter(LogBufferDescriptor.DefaultFrameHeader(logMetaDataBuffer)); }
/// <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); }
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); long rawTail = GetAndAddRawTail(alignedLength); int termId = LogBufferDescriptor.TermId(rawTail); long termOffset = rawTail & 0xFFFFFFFFL; UnsafeBuffer termBuffer = _termBuffer; int termLength = termBuffer.Capacity; 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); }
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); }
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)); }
public long AppendFragmentedMessage(HeaderWriter header, UnsafeBuffer 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 = LogBufferDescriptor.TermId(rawTail); long termOffset = rawTail & 0xFFFFFFFFL; UnsafeBuffer 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); }
public virtual long AppendUnfragmentedMessage(HeaderWriter header, UnsafeBuffer srcBuffer, int srcOffset, int length, ReservedValueSupplier reservedValueSupplier)
/// <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; }
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); }
/// <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; }
/// <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; }
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); }
/// <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="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="maxPayloadLength"> that the message will be fragmented into. </param> /// <param name="reservedValueSupplier"> <seealso cref="ReservedValueSupplier"/> for the frame. </param> /// <param name="activeTermId"> used for flow control. </param> /// <returns> the resulting offset of the term after the append on success otherwise <seealso cref="FAILED"/>. </returns> public int AppendFragmentedMessage( HeaderWriter header, IDirectBuffer bufferOne, int offsetOne, int lengthOne, IDirectBuffer bufferTwo, int offsetTwo, int lengthTwo, int maxPayloadLength, ReservedValueSupplier reservedValueSupplier, int activeTermId) { int length = lengthOne + lengthTwo; 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; long rawTail = GetAndAddRawTail(requiredLength); int termId = LogBufferDescriptor.TermId(rawTail); long termOffset = rawTail & 0xFFFF_FFFFL; 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; int positionOne = 0; int positionTwo = 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 { int remainingOne = lengthOne - positionOne; if (remainingOne > 0) { int numBytes = Math.Min(bytesToWrite - bytesWritten, remainingOne); termBuffer.PutBytes(payloadOffset, bufferOne, offsetOne + positionOne, numBytes); bytesWritten += numBytes; payloadOffset += numBytes; positionOne += numBytes; } else { int numBytes = Math.Min(bytesToWrite - bytesWritten, lengthTwo - positionTwo); termBuffer.PutBytes(payloadOffset, bufferTwo, offsetTwo + positionTwo, numBytes); bytesWritten += numBytes; payloadOffset += numBytes; positionTwo += numBytes; } } 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((int)resultingOffset); }
public virtual int AppendUnfragmentedMessage(HeaderWriter header, DirectBufferVector[] vectors, int length, ReservedValueSupplier reservedValueSupplier, int activeTermId)
public virtual int AppendUnfragmentedMessage(HeaderWriter header, IDirectBuffer srcBuffer, int srcOffset, int length, ReservedValueSupplier reservedValueSupplier, int activeTermId)