use of org.agrona.concurrent.UnsafeBuffer in project Aeron by real-logic.
the class BufferBuilderTest method shouldCompactBufferToLowerLimit.
@Test
public void shouldCompactBufferToLowerLimit() {
final int bufferLength = INITIAL_CAPACITY / 2;
final byte[] buffer = new byte[bufferLength];
final UnsafeBuffer srcBuffer = new UnsafeBuffer(buffer);
final BufferBuilder bufferBuilder = new BufferBuilder();
final int bufferCount = 5;
for (int i = 0; i < bufferCount; i++) {
bufferBuilder.append(srcBuffer, 0, buffer.length);
}
final int expectedLimit = buffer.length * bufferCount;
assertThat(bufferBuilder.limit(), is(expectedLimit));
final int expandedCapacity = bufferBuilder.capacity();
assertThat(expandedCapacity, greaterThan(expectedLimit));
bufferBuilder.reset();
bufferBuilder.append(srcBuffer, 0, buffer.length);
bufferBuilder.append(srcBuffer, 0, buffer.length);
bufferBuilder.append(srcBuffer, 0, buffer.length);
bufferBuilder.compact();
assertThat(bufferBuilder.limit(), is(buffer.length * 3));
assertThat(bufferBuilder.capacity(), lessThan(expandedCapacity));
}
use of org.agrona.concurrent.UnsafeBuffer in project Aeron by real-logic.
the class FragmentAssemblerTest method shouldDoNotingIfEndArrivesWithoutBegin.
@Test
public void shouldDoNotingIfEndArrivesWithoutBegin() {
when(header.flags()).thenReturn(FrameDescriptor.END_FRAG_FLAG);
final UnsafeBuffer srcBuffer = new UnsafeBuffer(new byte[1024]);
final int offset = 0;
final int length = srcBuffer.capacity() / 2;
adapter.onFragment(srcBuffer, offset, length, header);
verify(delegateFragmentHandler, never()).onFragment(any(), anyInt(), anyInt(), any());
}
use of org.agrona.concurrent.UnsafeBuffer in project Aeron by real-logic.
the class Image method rawPoll.
/**
* 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 RawBlockHandler} up to a limited number of bytes.
*
* This method is useful for operations like bulk archiving a stream to file.
*
* @param rawBlockHandler to which block is delivered.
* @param blockLengthLimit up to which a block may be in length.
* @return the number of bytes that have been consumed.
*/
public int rawPoll(final RawBlockHandler rawBlockHandler, final int blockLengthLimit) {
if (isClosed) {
return 0;
}
final long position = subscriberPosition.get();
final int termOffset = (int) position & termLengthMask;
final int activeIndex = indexByPosition(position, positionBitsToShift);
final UnsafeBuffer termBuffer = termBuffers[activeIndex];
final int capacity = termBuffer.capacity();
final int limit = Math.min(termOffset + blockLengthLimit, capacity);
final int resultingOffset = TermBlockScanner.scan(termBuffer, termOffset, limit);
final int length = resultingOffset - termOffset;
if (resultingOffset > termOffset) {
try {
final long fileOffset = ((long) capacity * activeIndex) + termOffset;
final int termId = termBuffer.getInt(termOffset + TERM_ID_FIELD_OFFSET, LITTLE_ENDIAN);
rawBlockHandler.onBlock(logBuffers.fileChannel(), fileOffset, termBuffer, termOffset, length, sessionId, termId);
} catch (final Throwable t) {
errorHandler.onError(t);
}
subscriberPosition.setOrdered(position + length);
}
return length;
}
use of org.agrona.concurrent.UnsafeBuffer in project Aeron by real-logic.
the class ExclusiveTermAppender method appendUnfragmentedMessage.
/**
* Append an unfragmented message to the the term buffer.
*
* @param termId for the current term.
* @param termOffset in the term at which to append.
* @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}.
*/
public int appendUnfragmentedMessage(final int termId, final int termOffset, 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 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);
termBuffer.putBytes(termOffset + HEADER_LENGTH, srcBuffer, srcOffset, length);
if (null != reservedValueSupplier) {
final long reservedValue = reservedValueSupplier.get(termBuffer, termOffset, frameLength);
termBuffer.putLong(termOffset + RESERVED_VALUE_OFFSET, reservedValue, LITTLE_ENDIAN);
}
frameLengthOrdered(termBuffer, termOffset, frameLength);
}
return resultingOffset;
}
use of org.agrona.concurrent.UnsafeBuffer in project Aeron by real-logic.
the class ExclusiveTermAppender method appendFragmentedMessage.
/**
* Append a fragmented message to the the term buffer.
* The message will be split up into fragments of MTU length minus header.
*
* @param termId for the current term.
* @param termOffset in the term at which to append.
* @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 maxPayloadLength that the message will be fragmented into.
* @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}.
*/
public int appendFragmentedMessage(final int termId, final int termOffset, final HeaderWriter header, final DirectBuffer srcBuffer, final int srcOffset, final int length, final int maxPayloadLength, final ReservedValueSupplier reservedValueSupplier) {
final int numMaxPayloads = length / maxPayloadLength;
final int remainingPayload = length % maxPayloadLength;
final int lastFrameLength = remainingPayload > 0 ? align(remainingPayload + HEADER_LENGTH, FRAME_ALIGNMENT) : 0;
final int requiredLength = (numMaxPayloads * (maxPayloadLength + HEADER_LENGTH)) + lastFrameLength;
final UnsafeBuffer termBuffer = this.termBuffer;
final int termLength = termBuffer.capacity();
putRawTailOrdered(termId, termOffset + requiredLength);
int resultingOffset = termOffset + requiredLength;
if (resultingOffset > termLength) {
resultingOffset = handleEndOfLogCondition(termBuffer, termOffset, header, termLength, termId);
} else {
int offset = termOffset;
byte flags = BEGIN_FRAG_FLAG;
int remaining = length;
do {
final int bytesToWrite = Math.min(remaining, maxPayloadLength);
final int frameLength = bytesToWrite + HEADER_LENGTH;
final int alignedLength = align(frameLength, FRAME_ALIGNMENT);
header.write(termBuffer, offset, frameLength, termId);
termBuffer.putBytes(offset + HEADER_LENGTH, srcBuffer, srcOffset + (length - remaining), bytesToWrite);
if (remaining <= maxPayloadLength) {
flags |= END_FRAG_FLAG;
}
frameFlags(termBuffer, offset, flags);
if (null != reservedValueSupplier) {
final long reservedValue = reservedValueSupplier.get(termBuffer, offset, frameLength);
termBuffer.putLong(offset + RESERVED_VALUE_OFFSET, reservedValue, LITTLE_ENDIAN);
}
frameLengthOrdered(termBuffer, offset, frameLength);
flags = 0;
offset += alignedLength;
remaining -= bytesToWrite;
} while (remaining > 0);
}
return resultingOffset;
}
Aggregations