/// <inheritdoc /> public override long TryClaim(int length, BufferClaim bufferClaim) { CheckPayloadLength(length); long newPosition = CLOSED; if (!_isClosed) { long limit = _positionLimit.GetVolatile(); int termCount = LogBufferDescriptor.ActiveTermCount(_logMetaDataBuffer); TermAppender termAppender = _termAppenders[LogBufferDescriptor.IndexByTermCount(termCount)]; long rawTail = termAppender.RawTailVolatile(); long termOffset = rawTail & 0xFFFF_FFFFL; int termId = LogBufferDescriptor.TermId(rawTail); long position = LogBufferDescriptor.ComputeTermBeginPosition(termId, PositionBitsToShift, InitialTermId) + termOffset; if (termCount != (termId - InitialTermId)) { return(ADMIN_ACTION); } if (position < limit) { int resultingOffset = termAppender.Claim(_headerWriter, length, bufferClaim, termId); newPosition = NewPosition(termCount, (int)termOffset, termId, position, resultingOffset); } else { newPosition = BackPressureStatus(position, length); } } return(newPosition); }
private long NewPosition(int resultingOffset) { if (resultingOffset > 0) { _termOffset = resultingOffset; return(_termBeginPosition + resultingOffset); } if ((_termBeginPosition + TermBufferLength) >= MaxPossiblePosition) { return(MAX_POSITION_EXCEEDED); } int nextIndex = LogBufferDescriptor.NextPartitionIndex(_activePartitionIndex); int nextTermId = _termId + 1; _activePartitionIndex = nextIndex; _termOffset = 0; _termId = nextTermId; _termBeginPosition = LogBufferDescriptor.ComputeTermBeginPosition(nextTermId, PositionBitsToShift, InitialTermId); var termCount = nextTermId - InitialTermId; LogBufferDescriptor.InitialiseTailWithTermId(_logMetaDataBuffer, nextIndex, nextTermId); LogBufferDescriptor.ActiveTermCountOrdered(_logMetaDataBuffer, termCount); return(ADMIN_ACTION); }
/// <summary> /// Try to claim a range in the publication log into which a message can be written with zero copy semantics. /// Once the message has been written then <seealso cref="BufferClaim#commit()"/> should be called thus making it available. /// <para> /// <b>Note:</b> This method can only be used for message lengths less than MTU length minus header. /// /// <pre>{@code /// final BufferClaim bufferClaim = new BufferClaim(); // Can be stored and reused to avoid allocation /// /// if (publication.tryClaim(messageLength, bufferClaim) > 0L) /// { /// try /// { /// final MutableDirectBuffer buffer = bufferClaim.buffer(); /// final int offset = bufferClaim.offset(); /// /// // Work with buffer directly or wrap with a flyweight /// } /// finally /// { /// bufferClaim.commit(); /// } /// } /// }</pre> /// /// </para> /// </summary> /// <param name="length"> of the range to claim, in bytes.. </param> /// <param name="bufferClaim"> to be populated if the claim succeeds. </param> /// <returns> The new stream position, otherwise <seealso cref="NOT_CONNECTED"/>, <seealso cref="BACK_PRESSURED"/>, /// <seealso cref="ADMIN_ACTION"/> or <seealso cref="CLOSED"/>. </returns> /// <exception cref="ArgumentException"> if the length is greater than max payload length within an MTU. </exception> /// <seealso cref="BufferClaim.Commit()" /> /// <seealso cref="BufferClaim.Abort()" /> public long TryClaim(int length, BufferClaim bufferClaim) { var newPosition = CLOSED; if (!_isClosed) { CheckForMaxPayloadLength(length); var limit = _positionLimit.Volatile; var partitionIndex = LogBufferDescriptor.ActivePartitionIndex(_logMetaDataBuffer); var termAppender = _termAppenders[partitionIndex]; var rawTail = termAppender.RawTailVolatile(); var termOffset = rawTail & 0xFFFFFFFFL; var position = LogBufferDescriptor.ComputeTermBeginPosition(LogBufferDescriptor.TermId(rawTail), _positionBitsToShift, InitialTermId) + termOffset; if (position < limit) { var result = termAppender.Claim(_headerWriter, length, bufferClaim); newPosition = NewPosition(partitionIndex, (int)termOffset, position, result); } else if (_clientConductor.IsPublicationConnected(LogBufferDescriptor.TimeOfLastStatusMessage(_logMetaDataBuffer))) { newPosition = BACK_PRESSURED; } else { newPosition = NOT_CONNECTED; } } return(newPosition); }
public long TryClaim(int length, BufferClaim bufferClaim) { CheckForMaxPayloadLength(length); var newPosition = CLOSED; if (!_isClosed) { var limit = _positionLimit.Volatile; var partitionIndex = LogBufferDescriptor.ActivePartitionIndex(_logMetaDataBuffer); var termAppender = _termAppenders[partitionIndex]; var rawTail = termAppender.RawTailVolatile(); var termOffset = rawTail & 0xFFFFFFFFL; var position = LogBufferDescriptor.ComputeTermBeginPosition(LogBufferDescriptor.TermId(rawTail), _positionBitsToShift, InitialTermId) + termOffset; if (position < limit) { var result = termAppender.Claim(_headerWriter, length, bufferClaim); newPosition = NewPosition(partitionIndex, (int)termOffset, position, result); } else { newPosition = BackPressureStatus(position, length); } } return(newPosition); }
/// <inheritdoc /> public override long Offer(IDirectBuffer buffer, int offset, int length, ReservedValueSupplier reservedValueSupplier = null) { long newPosition = CLOSED; if (!_isClosed) { long limit = _positionLimit.GetVolatile(); int termCount = LogBufferDescriptor.ActiveTermCount(_logMetaDataBuffer); TermAppender termAppender = _termAppenders[LogBufferDescriptor.IndexByTermCount(termCount)]; long rawTail = termAppender.RawTailVolatile(); long termOffset = rawTail & 0xFFFF_FFFFL; int termId = LogBufferDescriptor.TermId(rawTail); long position = LogBufferDescriptor.ComputeTermBeginPosition(termId, PositionBitsToShift, InitialTermId) + termOffset; if (termCount != (termId - InitialTermId)) { return(ADMIN_ACTION); } if (position < limit) { int resultingOffset; if (length <= MaxPayloadLength) { CheckPositiveLength(length); resultingOffset = termAppender.AppendUnfragmentedMessage( _headerWriter, buffer, offset, length, reservedValueSupplier, termId); } else { CheckMaxMessageLength(length); resultingOffset = termAppender.AppendFragmentedMessage( _headerWriter, buffer, offset, length, MaxPayloadLength, reservedValueSupplier, termId); } newPosition = NewPosition(termCount, (int)termOffset, termId, position, resultingOffset); } else { newPosition = BackPressureStatus(position, length); } } return(newPosition); }
internal ExclusivePublication( ClientConductor clientConductor, string channel, int streamId, int sessionId, IReadablePosition positionLimit, LogBuffers logBuffers, long originalRegistrationId, long registrationId) { var buffers = logBuffers.TermBuffers(); var logMetaDataBuffer = logBuffers.MetaDataBuffer(); for (var i = 0; i < LogBufferDescriptor.PARTITION_COUNT; i++) { _termAppenders[i] = new ExclusiveTermAppender(buffers[i], logMetaDataBuffer, i); } var termLength = logBuffers.TermLength(); _termBufferLength = termLength; MaxPayloadLength = LogBufferDescriptor.MtuLength(logMetaDataBuffer) - DataHeaderFlyweight.HEADER_LENGTH; MaxMessageLength = FrameDescriptor.ComputeExclusiveMaxMessageLength(termLength); _maxPossiblePosition = termLength * (1L << 31); _conductor = clientConductor; Channel = channel; StreamId = streamId; SessionId = sessionId; _logMetaDataBuffer = logMetaDataBuffer; _originalRegistrationId = originalRegistrationId; RegistrationId = registrationId; _positionLimit = positionLimit; _logBuffers = logBuffers; _positionBitsToShift = IntUtil.NumberOfTrailingZeros(termLength); _headerWriter = new HeaderWriter(LogBufferDescriptor.DefaultFrameHeader(logMetaDataBuffer)); InitialTermId = LogBufferDescriptor.InitialTermId(logMetaDataBuffer); var activeIndex = LogBufferDescriptor.ActivePartitionIndex(logMetaDataBuffer); _activePartitionIndex = activeIndex; long rawTail = LogBufferDescriptor.RawTail(_logMetaDataBuffer, activeIndex); _termId = LogBufferDescriptor.TermId(rawTail); _termOffset = LogBufferDescriptor.TermOffset(rawTail, termLength); _termBeginPosition = LogBufferDescriptor.ComputeTermBeginPosition(_termId, _positionBitsToShift, InitialTermId); }
public long Offer( UnsafeBuffer buffer, int offset, int length, ReservedValueSupplier reservedValueSupplier = null) { var newPosition = CLOSED; if (!_isClosed) { var limit = _positionLimit.Volatile; var partitionIndex = LogBufferDescriptor.ActivePartitionIndex(_logMetaDataBuffer); var termAppender = _termAppenders[partitionIndex]; var rawTail = termAppender.RawTailVolatile(); var termOffset = rawTail & 0xFFFFFFFFL; var position = LogBufferDescriptor.ComputeTermBeginPosition(LogBufferDescriptor.TermId(rawTail), _positionBitsToShift, InitialTermId) + termOffset; if (position < limit) { long result; if (length <= MaxPayloadLength) { result = termAppender.AppendUnfragmentedMessage(_headerWriter, buffer, offset, length, reservedValueSupplier); } else { CheckForMaxMessageLength(length); result = termAppender.AppendFragmentedMessage(_headerWriter, buffer, offset, length, MaxPayloadLength, reservedValueSupplier); } newPosition = NewPosition(partitionIndex, (int)termOffset, position, result); } else if (_conductor.IsPublicationConnected(LogBufferDescriptor.TimeOfLastStatusMessage(_logMetaDataBuffer))) { newPosition = BACK_PRESSURED; } else { newPosition = NOT_CONNECTED; } } return(newPosition); }
internal ExclusivePublication( ClientConductor clientConductor, string channel, int streamId, int sessionId, IReadablePosition positionLimit, int channelStatusId, LogBuffers logBuffers, long originalRegistrationId, long registrationId) : base( clientConductor, channel, streamId, sessionId, positionLimit, channelStatusId, logBuffers, originalRegistrationId, registrationId, FrameDescriptor.ComputeExclusiveMaxMessageLength(logBuffers.TermLength()) ) { var buffers = logBuffers.DuplicateTermBuffers(); var logMetaDataBuffer = logBuffers.MetaDataBuffer(); for (var i = 0; i < LogBufferDescriptor.PARTITION_COUNT; i++) { _termAppenders[i] = new ExclusiveTermAppender(buffers[i], logMetaDataBuffer, i); } var termCount = LogBufferDescriptor.ActiveTermCount(logMetaDataBuffer); var index = LogBufferDescriptor.IndexByTermCount(termCount); _activePartitionIndex = index; var rawTail = LogBufferDescriptor.RawTail(_logMetaDataBuffer, index); _termId = LogBufferDescriptor.TermId(rawTail); _termOffset = LogBufferDescriptor.TermOffset(rawTail); _termBeginPosition = LogBufferDescriptor.ComputeTermBeginPosition(_termId, _positionBitsToShift, InitialTermId); }
private long NewPosition(int resultingOffset) { if (resultingOffset > 0) { _termOffset = resultingOffset; return(_termBeginPosition + resultingOffset); } else { int nextIndex = LogBufferDescriptor.NextPartitionIndex(_activePartitionIndex); int nextTermId = _termId + 1; _activePartitionIndex = nextIndex; _termOffset = 0; _termId = nextTermId; _termBeginPosition = LogBufferDescriptor.ComputeTermBeginPosition(nextTermId, _positionBitsToShift, InitialTermId); _termAppenders[nextIndex].TailTermId(nextTermId); LogBufferDescriptor.ActivePartitionIndexOrdered(_logMetaDataBuffer, nextIndex); return(ADMIN_ACTION); } }