@Override public DirectBuffer next() { final int framedFragmentLength = bufferView.getInt(DataFrameDescriptor.lengthOffset(iterationOffset)); final int fragmentLength = DataFrameDescriptor.messageLength(framedFragmentLength); final int messageOffset = DataFrameDescriptor.messageOffset(iterationOffset); buffer.wrap(bufferView, messageOffset, fragmentLength); iterationOffset += DataFrameDescriptor.alignedLength(framedFragmentLength); return buffer; } }
@Override public int getStreamId() { return buffer.getInt(streamIdOffset(fragmentOffset), Protocol.ENDIANNESS); }
@Override public int getType() { return buffer.getShort(typeOffset(fragmentOffset), Protocol.ENDIANNESS); }
public static int alignedFramedLength(int msgLength) { return alignedLength(framedLength(msgLength)); }
@Override public int getMessageLength() { return messageLength(buffer.getInt(lengthOffset(fragmentOffset), Protocol.ENDIANNESS)); }
/** * Add a new fragment to the batch. * * @param length the length of the fragment * @param streamId the stream id of the fragment * @return the position of the fragment * @throws IllegalArgumentException if the given length is greater than the remaining capacity. In * this case, you should try with smaller length, or abort the whole batch. */ @SuppressWarnings("restriction") public long nextFragment(int length, int streamId) { currentOffset = nextOffset; final int framedLength = framedLength(length); nextOffset += alignedLength(framedLength); // ensure that there is enough capacity for padding message, or less than frame alignment which // omits the padding message final int remainingCapacity = buffer.capacity() - nextOffset; if (remainingCapacity < 0 || (FRAME_ALIGNMENT <= remainingCapacity && remainingCapacity < HEADER_LENGTH)) { throw new IllegalArgumentException( String.format(ERROR_MESSAGE, currentOffset, length, buffer.capacity())); } // set negative length => uncommitted fragment buffer.putIntOrdered(lengthOffset(currentOffset), -framedLength); UNSAFE.storeFence(); buffer.putShort(typeOffset(currentOffset), TYPE_MESSAGE); buffer.putInt(streamIdOffset(currentOffset), streamId); return position(partitionId, partitionOffset + nextOffset); }
final int framedLength = buffer.getIntVolatile(lengthOffset(fragmentOffset)); if (framedLength <= 0) { break; final short type = buffer.getShort(typeOffset(fragmentOffset)); if (type == TYPE_PADDING) { fragmentOffset += alignedLength(framedLength); final int streamId = buffer.getInt(streamIdOffset(fragmentOffset)); final int flagsOffset = flagsOffset(fragmentOffset); final byte flags = buffer.getByte(flagsOffset); try { final boolean isMarkedAsFailed = flagFailed(flags); final int messageLength = messageLength(framedLength); final int handlerResult = frgHandler.onFragment( buffer, messageOffset(fragmentOffset), messageLength, streamId, isMarkedAsFailed); buffer.putByte(flagsOffset, DataFrameDescriptor.enableFlagFailed(flags)); fragmentOffset += alignedLength(framedLength);
final int framedLength = buffer.getIntVolatile(lengthOffset(partitionOffset)); if (framedLength <= 0) { break; final short type = buffer.getShort(typeOffset(partitionOffset)); if (type == TYPE_PADDING) { partitionOffset += alignedLength(framedLength); final int streamId = buffer.getInt(streamIdOffset(partitionOffset)); if (readBytes == 0) { initialStreamId = streamId; final byte flags = buffer.getByte(flagsOffset(partitionOffset)); if (!isReadingBatch) { isReadingBatch = flagBatchBegin(flags); } else { isReadingBatch = !flagBatchEnd(flags); final int alignedFrameLength = alignedLength(framedLength); if (alignedFrameLength <= maxBlockSize - readBytes) { partitionOffset += alignedFrameLength;
/** Commit all fragments of the batch so that it can be read by subscriptions. */ public void commit() { final int firstFragmentFramedLength = -buffer.getInt(lengthOffset(FIRST_FRAGMENT_OFFSET)); // do not set batch flags if only one fragment in the batch if (currentOffset > 0) { // set batch begin flag final byte firstFragmentFlags = buffer.getByte(flagsOffset(FIRST_FRAGMENT_OFFSET)); buffer.putByte(flagsOffset(FIRST_FRAGMENT_OFFSET), enableFlagBatchBegin(firstFragmentFlags)); // set positive length => commit fragment int fragmentOffset = DataFrameDescriptor.alignedLength(firstFragmentFramedLength); while (fragmentOffset < nextOffset) { final int fragmentFramedLength = -buffer.getInt(lengthOffset(fragmentOffset)); buffer.putInt(lengthOffset(fragmentOffset), fragmentFramedLength); fragmentOffset += DataFrameDescriptor.alignedLength(fragmentFramedLength); } // set batch end flag final byte lastFragmentFlags = buffer.getByte(flagsOffset(currentOffset)); buffer.putByte(flagsOffset(currentOffset), enableFlagBatchEnd(lastFragmentFlags)); } fillRemainingBatchSize(); // commit the first fragment at the end so that the batch can be read at // once buffer.putIntOrdered(lengthOffset(FIRST_FRAGMENT_OFFSET), firstFragmentFramedLength); onCompleteHandler.run(); reset(); }
private void fillRemainingBatchSize() { // since the claimed batch size can be longer than the written fragment // size, we need to fill the rest with a padding fragment final int remainingLength = buffer.capacity() - nextOffset; if (remainingLength >= HEADER_LENGTH) { buffer.putInt(lengthOffset(nextOffset), remainingLength); buffer.putShort(typeOffset(nextOffset), TYPE_PADDING); } }
/** * Commit all fragments of the batch and mark them as failed. They will be ignored by * subscriptions. */ public void abort() { // discard all fragments by set the type to padding int fragmentOffset = 0; while (fragmentOffset < nextOffset) { final int fragmentLength = -buffer.getInt(lengthOffset(fragmentOffset)); buffer.putInt(typeOffset(fragmentOffset), TYPE_PADDING); buffer.putIntOrdered(lengthOffset(fragmentOffset), fragmentLength); fragmentOffset += DataFrameDescriptor.alignedLength(fragmentLength); } fillRemainingBatchSize(); onCompleteHandler.run(); reset(); }
/** * Finish reading and consume the fragments (i.e. update the subscription position). Mark all * fragments as failed. */ public void markFailed() { int fragmentOffset = 0; while (fragmentOffset < blockLength) { int framedFragmentLength = bufferView.getInt(DataFrameDescriptor.lengthOffset(fragmentOffset)); if (framedFragmentLength < 0) { framedFragmentLength = -framedFragmentLength; } final int frameLength = DataFrameDescriptor.alignedLength(framedFragmentLength); final int flagsOffset = DataFrameDescriptor.flagsOffset(fragmentOffset); final byte flags = bufferView.getByte(flagsOffset); bufferView.putByte(flagsOffset, DataFrameDescriptor.enableFlagFailed(flags)); fragmentOffset += frameLength; } updatePosition(); }
public static int getFragmentLength(final DirectBuffer buffer, final int offset) { return alignedLength(buffer.getInt(lengthOffset(offset), Protocol.ENDIANNESS)); }
public void wrap(final DirectBuffer buffer, final int offset) { this.fragmentOffset = offset; this.messageOffset = messageOffset(fragmentOffset); this.buffer = buffer; }
public static int getFramedMessageLength(int messageLength) { return DataFrameDescriptor.alignedLength(MESSAGE_HEADER_LENGTH + messageLength); }
protected Answer<?> claimFragment(final long offset) { return invocation -> { final ClaimedFragment claimedFragment = (ClaimedFragment) invocation.getArguments()[0]; final int length = (int) invocation.getArguments()[1]; fragmentOffset = claimedFragment.getOffset(); claimedFragment.wrap(sendBuffer, 0, alignedFramedLength(length), () -> {}); final long claimedPosition = offset + alignedFramedLength(length); return claimedPosition; }; }
/** Commit the fragment so that it can be read by subscriptions. */ public void commit() { // commit the message by writing the positive framed length buffer.putIntOrdered(lengthOffset(0), buffer.capacity()); onCompleteHandler.run(); reset(); }
@SuppressWarnings("restriction") public int appendFrame( final LogBufferPartition partition, final int activePartitionId, final DirectBuffer msg, final int start, final int length, final int streamId) { final int partitionSize = partition.getPartitionSize(); final int framedLength = framedLength(length); final int alignedFrameLength = alignedLength(framedLength); // move the tail of the partition final int frameOffset = partition.getAndAddTail(alignedFrameLength); int newTail = frameOffset + alignedFrameLength; if (newTail <= (partitionSize - HEADER_LENGTH)) { final UnsafeBuffer buffer = partition.getDataBuffer(); // write negative length field buffer.putIntOrdered(lengthOffset(frameOffset), -framedLength); UNSAFE.storeFence(); buffer.putShort(typeOffset(frameOffset), TYPE_MESSAGE); buffer.putInt(streamIdOffset(frameOffset), streamId); buffer.putBytes(messageOffset(frameOffset), msg, start, length); // commit the message buffer.putIntOrdered(lengthOffset(frameOffset), framedLength); } else { newTail = onEndOfPartition(partition, frameOffset); } return newTail; }
final int framedLength = buffer.getIntVolatile(lengthOffset(fragmentOffset)); if (framedLength <= 0) { break; final short type = buffer.getShort(typeOffset(fragmentOffset)); if (type == TYPE_PADDING) { fragmentOffset += alignedLength(framedLength); final int streamId = buffer.getInt(streamIdOffset(fragmentOffset)); final int flagsOffset = flagsOffset(fragmentOffset); final byte flags = buffer.getByte(flagsOffset); try { final boolean isMarkedAsFailed = flagFailed(flags); final int messageLength = messageLength(framedLength); final int handlerResult = frgHandler.onFragment( buffer, messageOffset(fragmentOffset), messageLength, streamId, isMarkedAsFailed); buffer.putByte(flagsOffset, DataFrameDescriptor.enableFlagFailed(flags)); fragmentOffset += alignedLength(framedLength);
final int framedLength = buffer.getIntVolatile(lengthOffset(partitionOffset)); if (framedLength <= 0) { break; final short type = buffer.getShort(typeOffset(partitionOffset)); if (type == TYPE_PADDING) { partitionOffset += alignedLength(framedLength); final int streamId = buffer.getInt(streamIdOffset(partitionOffset)); if (readBytes == 0) { initialStreamId = streamId; final byte flags = buffer.getByte(flagsOffset(partitionOffset)); if (!isReadingBatch) { isReadingBatch = flagBatchBegin(flags); } else { isReadingBatch = !flagBatchEnd(flags); final int alignedFrameLength = alignedLength(framedLength); if (alignedFrameLength <= maxBlockSize - readBytes) { partitionOffset += alignedFrameLength;