use of org.agrona.concurrent.UnsafeBuffer in project Aeron by real-logic.
the class Image method controlledPoll.
/**
* Poll for new messages in a stream. If new messages are found beyond the last consumed position then they
* will be delivered to the {@link ControlledFragmentHandler} up to a limited number of fragments as specified.
*
* To assemble messages that span multiple fragments then use {@link ControlledFragmentAssembler}.
*
* @param fragmentHandler to which message fragments are delivered.
* @param fragmentLimit for the number of fragments to be consumed during one polling operation.
* @return the number of fragments that have been consumed.
* @see ControlledFragmentAssembler
*/
public int controlledPoll(final ControlledFragmentHandler fragmentHandler, final int fragmentLimit) {
if (isClosed) {
return 0;
}
long position = subscriberPosition.get();
int termOffset = (int) position & termLengthMask;
int resultingOffset = termOffset;
int fragmentsRead = 0;
final UnsafeBuffer termBuffer = activeTermBuffer(position);
try {
final int capacity = termBuffer.capacity();
do {
final int length = frameLengthVolatile(termBuffer, resultingOffset);
if (length <= 0) {
break;
}
final int frameOffset = resultingOffset;
final int alignedLength = BitUtil.align(length, FRAME_ALIGNMENT);
resultingOffset += alignedLength;
if (!isPaddingFrame(termBuffer, frameOffset)) {
header.buffer(termBuffer);
header.offset(frameOffset);
final Action action = fragmentHandler.onFragment(termBuffer, frameOffset + HEADER_LENGTH, length - HEADER_LENGTH, header);
++fragmentsRead;
if (action == BREAK) {
break;
} else if (action == ABORT) {
--fragmentsRead;
resultingOffset = frameOffset;
break;
} else if (action == COMMIT) {
position += alignedLength;
termOffset = resultingOffset;
subscriberPosition.setOrdered(position);
}
}
} while (fragmentsRead < fragmentLimit && resultingOffset < capacity);
} catch (final Throwable t) {
errorHandler.onError(t);
}
updatePosition(position, termOffset, resultingOffset);
return fragmentsRead;
}
use of org.agrona.concurrent.UnsafeBuffer in project Aeron by real-logic.
the class Image method poll.
/**
* Poll for new messages in a stream. If new messages are found beyond the last consumed position then they
* will be delivered to the {@link FragmentHandler} up to a limited number of fragments as specified.
*
* To assemble messages that span multiple fragments then use {@link FragmentAssembler}.
*
* @param fragmentHandler to which message fragments are delivered.
* @param fragmentLimit for the number of fragments to be consumed during one polling operation.
* @return the number of fragments that have been consumed.
* @see FragmentAssembler
*/
public int poll(final FragmentHandler fragmentHandler, final int fragmentLimit) {
if (isClosed) {
return 0;
}
final long position = subscriberPosition.get();
final int termOffset = (int) position & termLengthMask;
final UnsafeBuffer termBuffer = activeTermBuffer(position);
final long outcome = read(termBuffer, termOffset, fragmentHandler, fragmentLimit, header, errorHandler);
updatePosition(position, termOffset, offset(outcome));
return fragmentsRead(outcome);
}
use of org.agrona.concurrent.UnsafeBuffer in project Aeron by real-logic.
the class ExclusiveTermAppender method claim.
/**
* Claim length of a the term buffer for writing in the message with zero copy semantics.
*
* @param termId for the current term.
* @param termOffset in the term at which to append.
* @param header for writing the default header.
* @param length of the message to be written.
* @param bufferClaim to be updated with the claimed region.
* @return the resulting offset of the term after the append on success otherwise {@link #TRIPPED} or
* {@link #FAILED}.
*/
public int claim(final int termId, final int termOffset, final HeaderWriter header, final int length, final ExclusiveBufferClaim bufferClaim) {
final int frameLength = length + HEADER_LENGTH;
final int alignedLength = align(frameLength, FRAME_ALIGNMENT);
final UnsafeBuffer termBuffer = this.termBuffer;
final int termLength = termBuffer.capacity();
putRawTailOrdered(termId, termOffset + alignedLength);
int resultingOffset = termOffset + alignedLength;
if (resultingOffset > termLength) {
resultingOffset = handleEndOfLogCondition(termBuffer, termOffset, header, termLength, termId);
} else {
header.write(termBuffer, termOffset, frameLength, termId);
bufferClaim.wrap(termBuffer, termOffset, frameLength);
}
return resultingOffset;
}
use of org.agrona.concurrent.UnsafeBuffer in project Aeron by real-logic.
the class LogBufferUnblocker method unblock.
/**
* Attempt to unblock a log buffer at given position
*
* @param termBuffers for current blockedOffset
* @param logMetaDataBuffer for log buffer
* @param blockedPosition to attempt to unblock
* @return whether unblocked or not
*/
public static boolean unblock(final UnsafeBuffer[] termBuffers, final UnsafeBuffer logMetaDataBuffer, final long blockedPosition) {
final int termLength = termBuffers[0].capacity();
final int positionBitsToShift = Integer.numberOfTrailingZeros(termLength);
final int index = indexByPosition(blockedPosition, positionBitsToShift);
final UnsafeBuffer termBuffer = termBuffers[index];
final long rawTail = rawTailVolatile(logMetaDataBuffer, index);
final int termId = termId(rawTail);
final int tailOffset = termOffset(rawTail, termLength);
final int blockedOffset = computeTermOffsetFromPosition(blockedPosition, positionBitsToShift);
boolean result = false;
switch(TermUnblocker.unblock(logMetaDataBuffer, termBuffer, blockedOffset, tailOffset, termId)) {
case UNBLOCKED_TO_END:
rotateLog(logMetaDataBuffer, index, termId + 1);
// fall through
case UNBLOCKED:
result = true;
}
return result;
}
use of org.agrona.concurrent.UnsafeBuffer in project Aeron by real-logic.
the class TermAppender method appendUnfragmentedMessage.
/**
* Append an unfragmented message to the the term buffer.
*
* @param header for writing the default header.
* @param srcBuffer containing the message.
* @param srcOffset at which the message begins.
* @param length of the message in the source buffer.
* @param reservedValueSupplier {@link ReservedValueSupplier} for the frame.
* @return the resulting offset of the term after the append on success otherwise {@link #TRIPPED} or
* {@link #FAILED} packed with the termId if a padding record was inserted at the end.
*/
public long appendUnfragmentedMessage(final HeaderWriter header, final DirectBuffer srcBuffer, final int srcOffset, final int length, final ReservedValueSupplier reservedValueSupplier) {
final int frameLength = length + HEADER_LENGTH;
final int alignedLength = align(frameLength, FRAME_ALIGNMENT);
final long rawTail = getAndAddRawTail(alignedLength);
final long termOffset = rawTail & 0xFFFF_FFFFL;
final UnsafeBuffer termBuffer = this.termBuffer;
final int termLength = termBuffer.capacity();
long resultingOffset = termOffset + alignedLength;
if (resultingOffset > termLength) {
resultingOffset = handleEndOfLogCondition(termBuffer, termOffset, header, termLength, termId(rawTail));
} else {
final int offset = (int) termOffset;
header.write(termBuffer, offset, frameLength, termId(rawTail));
termBuffer.putBytes(offset + HEADER_LENGTH, srcBuffer, srcOffset, length);
if (null != reservedValueSupplier) {
final long reservedValue = reservedValueSupplier.get(termBuffer, offset, frameLength);
termBuffer.putLong(offset + RESERVED_VALUE_OFFSET, reservedValue, LITTLE_ENDIAN);
}
frameLengthOrdered(termBuffer, offset, frameLength);
}
return resultingOffset;
}
Aggregations