Java Code Examples for org.agrona.concurrent.UnsafeBuffer#capacity()

The following examples show how to use org.agrona.concurrent.UnsafeBuffer#capacity() . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: RocksDbStorage.java    From deeplearning4j with Apache License 2.0 6 votes vote down vote up
/**
 * Add an ndarray to the storage
 *
 * @param array the array to add
 */
@Override
public void addUpdate(NDArrayMessage array) {
    UnsafeBuffer directBuffer = (UnsafeBuffer) NDArrayMessage.toBuffer(array);
    byte[] data = directBuffer.byteArray();
    if (data == null) {
        data = new byte[directBuffer.capacity()];
        directBuffer.getBytes(0, data, 0, data.length);
    }
    byte[] key = ByteBuffer.allocate(4).putInt(size).array();
    try {
        db.put(key, data);
    } catch (RocksDBException e) {
        throw new RuntimeException(e);
    }

    size++;

}
 
Example 2
Source File: SegmentInspector.java    From aeron with Apache License 2.0 6 votes vote down vote up
/**
 * Dump the contents of a segment file to a {@link PrintStream}.
 *
 * @param out              for the dumped contents.
 * @param messageDumpLimit for the number of bytes per message fragment to dump.
 * @param buffer           the wraps the segment file.
 */
public static void dumpSegment(final PrintStream out, final int messageDumpLimit, final UnsafeBuffer buffer)
{
    final DataHeaderFlyweight dataHeaderFlyweight = new DataHeaderFlyweight();
    final int length = buffer.capacity();
    int offset = 0;

    while (offset < length)
    {
        dataHeaderFlyweight.wrap(buffer, offset, length - offset);
        out.println(offset + ": " + dataHeaderFlyweight.toString());

        final int frameLength = dataHeaderFlyweight.frameLength();
        if (frameLength < DataHeaderFlyweight.HEADER_LENGTH)
        {
            break;
        }

        final int limit = min(frameLength - HEADER_LENGTH, messageDumpLimit);
        out.println(LogInspector.formatBytes(buffer, offset + HEADER_LENGTH, limit));
        offset += BitUtil.align(frameLength, FrameDescriptor.FRAME_ALIGNMENT);
    }
}
 
Example 3
Source File: MultiSubscriberTest.java    From aeron with Apache License 2.0 6 votes vote down vote up
private void verifyData(final UnsafeBuffer srcBuffer, final FragmentHandler mockFragmentHandler)
{
    final ArgumentCaptor<DirectBuffer> bufferArg = ArgumentCaptor.forClass(DirectBuffer.class);
    final ArgumentCaptor<Integer> offsetArg = ArgumentCaptor.forClass(Integer.class);

    verify(mockFragmentHandler, times(1)).onFragment(
        bufferArg.capture(), offsetArg.capture(), eq(srcBuffer.capacity()), any(Header.class));

    final DirectBuffer capturedBuffer = bufferArg.getValue();
    final int offset = offsetArg.getValue();
    for (int i = 0; i < srcBuffer.capacity(); i++)
    {
        final int index = offset + i;
        assertEquals(srcBuffer.getByte(i), capturedBuffer.getByte(index), "same at " + index);
    }
}
 
Example 4
Source File: LogBuffers.java    From aeron with Apache License 2.0 6 votes vote down vote up
/**
 * Pre touch memory pages so they are faulted in to be available before access.
 */
public void preTouch()
{
    final int value = 0;
    final int pageSize = LogBufferDescriptor.pageSize(logMetaDataBuffer);
    final UnsafeBuffer atomicBuffer = new UnsafeBuffer();

    for (final MappedByteBuffer buffer : mappedByteBuffers)
    {
        atomicBuffer.wrap(buffer);

        for (int i = 0, length = atomicBuffer.capacity(); i < length; i += pageSize)
        {
            atomicBuffer.compareAndSetInt(i, value, value);
        }
    }
}
 
Example 5
Source File: RocksDbStorage.java    From nd4j with Apache License 2.0 6 votes vote down vote up
/**
 * Add an ndarray to the storage
 *
 * @param array the array to add
 */
@Override
public void addUpdate(NDArrayMessage array) {
    UnsafeBuffer directBuffer = (UnsafeBuffer) NDArrayMessage.toBuffer(array);
    byte[] data = directBuffer.byteArray();
    if (data == null) {
        data = new byte[directBuffer.capacity()];
        directBuffer.getBytes(0, data, 0, data.length);
    }
    byte[] key = ByteBuffer.allocate(4).putInt(size).array();
    try {
        db.put(key, data);
    } catch (RocksDBException e) {
        throw new RuntimeException(e);
    }

    size++;

}
 
Example 6
Source File: FileReceiver.java    From aeron with Apache License 2.0 6 votes vote down vote up
private void fileChunk(
    final long correlationId,
    final long chunkOffset,
    final long chunkLength,
    final DirectBuffer buffer,
    final int offset)
{
    final UnsafeBuffer fileBuffer = fileSessionByIdMap.get(correlationId);
    buffer.getBytes(offset + CHUNK_PAYLOAD_OFFSET, fileBuffer, (int)chunkOffset, (int)chunkLength);

    if ((chunkOffset + chunkLength) >= fileBuffer.capacity())
    {
        fileSessionByIdMap.remove(correlationId);
        IoUtil.unmap(fileBuffer.byteBuffer());
    }
}
 
Example 7
Source File: FragmentAssemblerTest.java    From aeron with Apache License 2.0 5 votes vote down vote up
@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());
}
 
Example 8
Source File: FragmentAssemblerTest.java    From aeron with Apache License 2.0 5 votes vote down vote up
@Test
public void shouldAssembleFourPartMessage()
{
    when(header.flags())
        .thenReturn(FrameDescriptor.BEGIN_FRAG_FLAG)
        .thenReturn((byte)0)
        .thenReturn((byte)0)
        .thenReturn(FrameDescriptor.END_FRAG_FLAG);

    final UnsafeBuffer srcBuffer = new UnsafeBuffer(new byte[1024]);
    final int offset = 0;
    final int length = srcBuffer.capacity() / 4;

    for (int i = 0; i < 4; i++)
    {
        srcBuffer.setMemory(i * length, length, (byte)(65 + i));
    }

    adapter.onFragment(srcBuffer, offset, length, header);
    adapter.onFragment(srcBuffer, offset + length, length, header);
    adapter.onFragment(srcBuffer, offset + (length * 2), length, header);
    adapter.onFragment(srcBuffer, offset + (length * 3), length, header);

    final ArgumentCaptor<UnsafeBuffer> bufferArg = ArgumentCaptor.forClass(UnsafeBuffer.class);
    final ArgumentCaptor<Header> headerArg = ArgumentCaptor.forClass(Header.class);

    verify(delegateFragmentHandler, times(1)).onFragment(
        bufferArg.capture(), eq(offset), eq(length * 4), headerArg.capture());

    final UnsafeBuffer capturedBuffer = bufferArg.getValue();
    for (int i = 0; i < srcBuffer.capacity(); i++)
    {
        assertEquals(srcBuffer.getByte(i), capturedBuffer.getByte(i), "same at i=" + i);
    }

    final Header capturedHeader = headerArg.getValue();
    assertEquals(SESSION_ID, capturedHeader.sessionId());
    assertEquals(FrameDescriptor.END_FRAG_FLAG, capturedHeader.flags());
}
 
Example 9
Source File: Image.java    From aeron with Apache License 2.0 5 votes vote down vote up
/**
 * 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.
 * <p>
 * This method is useful for operations like bulk archiving a stream to file.
 * <p>
 * A scan will terminate if a padding frame is encountered. If first frame in a scan is padding then a block
 * for the padding is notified. If the padding comes after the first frame in a scan then the scan terminates
 * at the offset the padding frame begins. Padding frames are delivered singularly in a block.
 * <p>
 * Padding frames may be for a greater range than the limit offset but only the header needs to be valid so
 * relevant length of the frame is {@link io.aeron.protocol.DataHeaderFlyweight#HEADER_LENGTH}.
 *
 * @param handler          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 handler, final int blockLengthLimit)
{
    if (isClosed)
    {
        return 0;
    }

    final long position = subscriberPosition.get();
    final int offset = (int)position & termLengthMask;
    final int activeIndex = indexByPosition(position, positionBitsToShift);
    final UnsafeBuffer termBuffer = termBuffers[activeIndex];
    final int capacity = termBuffer.capacity();
    final int limitOffset = Math.min(offset + blockLengthLimit, capacity);
    final int resultingOffset = TermBlockScanner.scan(termBuffer, offset, limitOffset);
    final int length = resultingOffset - offset;

    if (resultingOffset > offset)
    {
        try
        {
            final long fileOffset = ((long)capacity * activeIndex) + offset;
            final int termId = termBuffer.getInt(offset + TERM_ID_FIELD_OFFSET, LITTLE_ENDIAN);

            handler.onBlock(logBuffers.fileChannel(), fileOffset, termBuffer, offset, length, sessionId, termId);
        }
        catch (final Throwable t)
        {
            errorHandler.onError(t);
        }
        finally
        {
            subscriberPosition.setOrdered(position + length);
        }
    }

    return length;
}
 
Example 10
Source File: TermAppenderTest.java    From aeron with Apache License 2.0 5 votes vote down vote up
@Test
public void shouldAppendUnfragmentedFromVectorsToEmptyLog()
{
    final int headerLength = DEFAULT_HEADER.capacity();
    final UnsafeBuffer bufferOne = new UnsafeBuffer(new byte[64]);
    final UnsafeBuffer bufferTwo = new UnsafeBuffer(new byte[256]);
    bufferOne.setMemory(0, bufferOne.capacity(), (byte)'1');
    bufferTwo.setMemory(0, bufferTwo.capacity(), (byte)'2');
    final int msgLength = bufferOne.capacity() + 200;
    final int frameLength = msgLength + headerLength;
    final int alignedFrameLength = align(frameLength, FRAME_ALIGNMENT);
    final int tail = 0;

    logMetaDataBuffer.putLong(TERM_TAIL_COUNTER_OFFSET, packTail(TERM_ID, tail));

    final DirectBufferVector[] vectors = new DirectBufferVector[]
    {
        new DirectBufferVector(bufferOne, 0, bufferOne.capacity()),
        new DirectBufferVector(bufferTwo, 0, 200)
    };

    assertEquals(
        alignedFrameLength, termAppender.appendUnfragmentedMessage(headerWriter, vectors, msgLength, RVS, TERM_ID));

    assertEquals(
        packTail(TERM_ID, tail + alignedFrameLength), rawTailVolatile(logMetaDataBuffer, PARTITION_INDEX));

    final InOrder inOrder = inOrder(termBuffer, headerWriter);
    inOrder.verify(headerWriter, times(1)).write(termBuffer, tail, frameLength, TERM_ID);
    inOrder.verify(termBuffer, times(1)).putBytes(headerLength, bufferOne, 0, bufferOne.capacity());
    inOrder.verify(termBuffer, times(1)).putBytes(headerLength + bufferOne.capacity(), bufferTwo, 0, 200);
    inOrder.verify(termBuffer, times(1)).putLong(tail + RESERVED_VALUE_OFFSET, RV, LITTLE_ENDIAN);
    inOrder.verify(termBuffer, times(1)).putIntOrdered(tail, frameLength);
}
 
Example 11
Source File: TwoBufferOfferMessageTest.java    From aeron with Apache License 2.0 5 votes vote down vote up
@Test
@Timeout(10)
public void shouldTransferUnfragmentedTwoPartMessage()
{
    final UnsafeBuffer expectedBuffer = new UnsafeBuffer(new byte[256]);
    final UnsafeBuffer bufferOne = new UnsafeBuffer(expectedBuffer, 0, 32);
    final UnsafeBuffer bufferTwo = new UnsafeBuffer(expectedBuffer, 32, expectedBuffer.capacity() - 32);

    bufferOne.setMemory(0, bufferOne.capacity(), (byte)'a');
    bufferTwo.setMemory(0, bufferTwo.capacity(), (byte)'b');
    final String expectedMessage = expectedBuffer.getStringWithoutLengthAscii(0, expectedBuffer.capacity());

    final MutableReference<String> receivedMessage = new MutableReference<>();
    final FragmentHandler fragmentHandler = (buffer, offset, length, header) ->
        receivedMessage.set(buffer.getStringWithoutLengthAscii(offset, length));

    try (Subscription subscription = aeron.addSubscription(CHANNEL, STREAM_ID))
    {
        try (Publication publication = aeron.addPublication(CHANNEL, STREAM_ID))
        {
            publishMessage(bufferOne, bufferTwo, publication);
            pollForMessage(subscription, receivedMessage, fragmentHandler);

            assertEquals(expectedMessage, receivedMessage.get());
        }

        try (Publication publication = aeron.addExclusivePublication(CHANNEL, STREAM_ID))
        {
            publishMessage(bufferOne, bufferTwo, publication);
            pollForMessage(subscription, receivedMessage, fragmentHandler);

            assertEquals(expectedMessage, receivedMessage.get());
        }
    }
}
 
Example 12
Source File: FileSender.java    From aeron with Apache License 2.0 5 votes vote down vote up
private static void streamChunks(final Publication publication, final long correlationId, final UnsafeBuffer buffer)
{
    final BufferClaim bufferClaim = new BufferClaim();
    final int fileLength = buffer.capacity();
    final int maxChunkLength = publication.maxPayloadLength() - CHUNK_PAYLOAD_OFFSET;
    int chunkOffset = 0;

    while (chunkOffset < fileLength)
    {
        final int chunkLength = Math.min(maxChunkLength, fileLength - chunkOffset);
        sendChunk(publication, bufferClaim, correlationId, buffer, chunkOffset, chunkLength);
        chunkOffset += chunkLength;
    }
}
 
Example 13
Source File: ExclusiveTermAppender.java    From aeron with Apache License 2.0 5 votes vote down vote up
/**
 * 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 #FAILED}.
 */
public int claim(
    final int termId,
    final int termOffset,
    final HeaderWriter header,
    final int length,
    final BufferClaim bufferClaim)
{
    final int frameLength = length + HEADER_LENGTH;
    final int alignedLength = align(frameLength, FRAME_ALIGNMENT);
    final UnsafeBuffer termBuffer = this.termBuffer;
    final 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);
        bufferClaim.wrap(termBuffer, termOffset, frameLength);
    }

    return resultingOffset;
}
 
Example 14
Source File: TwoBufferOfferMessageTest.java    From aeron with Apache License 2.0 5 votes vote down vote up
@Test
@Timeout(10)
public void shouldTransferFragmentedTwoPartMessage()
{
    final UnsafeBuffer expectedBuffer = new UnsafeBuffer(new byte[32 + driver.context().mtuLength()]);
    final UnsafeBuffer bufferOne = new UnsafeBuffer(expectedBuffer, 0, 32);
    final UnsafeBuffer bufferTwo = new UnsafeBuffer(expectedBuffer, 32, expectedBuffer.capacity() - 32);

    bufferOne.setMemory(0, bufferOne.capacity(), (byte)'a');
    bufferTwo.setMemory(0, bufferTwo.capacity(), (byte)'b');
    final String expectedMessage = expectedBuffer.getStringWithoutLengthAscii(0, expectedBuffer.capacity());

    final MutableReference<String> receivedMessage = new MutableReference<>();
    final FragmentHandler fragmentHandler = new FragmentAssembler((buffer, offset, length, header) ->
        receivedMessage.set(buffer.getStringWithoutLengthAscii(offset, length)));

    try (Subscription subscription = aeron.addSubscription(CHANNEL, STREAM_ID))
    {
        try (Publication publication = aeron.addPublication(CHANNEL, STREAM_ID))
        {
            publishMessage(bufferOne, bufferTwo, publication);
            pollForMessage(subscription, receivedMessage, fragmentHandler);

            assertEquals(expectedMessage, receivedMessage.get());
        }

        try (Publication publication = aeron.addExclusivePublication(CHANNEL, STREAM_ID))
        {
            publishMessage(bufferOne, bufferTwo, publication);
            pollForMessage(subscription, receivedMessage, fragmentHandler);

            assertEquals(expectedMessage, receivedMessage.get());
        }
    }
}
 
Example 15
Source File: ExclusiveTermAppender.java    From aeron with Apache License 2.0 4 votes vote down vote up
/**
 * 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 #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();

    int resultingOffset = termOffset + requiredLength;
    putRawTailOrdered(termId, resultingOffset);

    if (resultingOffset > termLength)
    {
        resultingOffset = handleEndOfLogCondition(termBuffer, termOffset, header, termLength, termId);
    }
    else
    {
        int frameOffset = 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, frameOffset, frameLength, termId);
            termBuffer.putBytes(
                frameOffset + HEADER_LENGTH,
                srcBuffer,
                srcOffset + (length - remaining),
                bytesToWrite);

            if (remaining <= maxPayloadLength)
            {
                flags |= END_FRAG_FLAG;
            }

            frameFlags(termBuffer, frameOffset, flags);

            if (null != reservedValueSupplier)
            {
                final long reservedValue = reservedValueSupplier.get(termBuffer, frameOffset, frameLength);
                termBuffer.putLong(frameOffset + RESERVED_VALUE_OFFSET, reservedValue, LITTLE_ENDIAN);
            }

            frameLengthOrdered(termBuffer, frameOffset, frameLength);

            flags = 0;
            frameOffset += alignedLength;
            remaining -= bytesToWrite;
        }
        while (remaining > 0);
    }

    return resultingOffset;
}
 
Example 16
Source File: ExclusiveTermAppender.java    From aeron with Apache License 2.0 4 votes vote down vote up
/**
 * 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 vectors               to the buffers.
 * @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 #FAILED}.
 */
public int appendFragmentedMessage(
    final int termId,
    final int termOffset,
    final HeaderWriter header,
    final DirectBufferVector[] vectors,
    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();

    int resultingOffset = termOffset + requiredLength;
    putRawTailOrdered(termId, resultingOffset);

    if (resultingOffset > termLength)
    {
        resultingOffset = handleEndOfLogCondition(termBuffer, termOffset, header, termLength, termId);
    }
    else
    {
        int frameOffset = termOffset;
        byte flags = BEGIN_FRAG_FLAG;
        int remaining = length;
        int vectorIndex = 0;
        int vectorOffset = 0;

        do
        {
            final int bytesToWrite = Math.min(remaining, maxPayloadLength);
            final int frameLength = bytesToWrite + HEADER_LENGTH;
            final int alignedLength = align(frameLength, FRAME_ALIGNMENT);

            header.write(termBuffer, frameOffset, frameLength, termId);

            int bytesWritten = 0;
            int payloadOffset = frameOffset + HEADER_LENGTH;
            do
            {
                final DirectBufferVector vector = vectors[vectorIndex];
                final int vectorRemaining = vector.length - vectorOffset;
                final 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 |= END_FRAG_FLAG;
            }

            frameFlags(termBuffer, frameOffset, flags);

            if (null != reservedValueSupplier)
            {
                final long reservedValue = reservedValueSupplier.get(termBuffer, frameOffset, frameLength);
                termBuffer.putLong(frameOffset + RESERVED_VALUE_OFFSET, reservedValue, LITTLE_ENDIAN);
            }

            frameLengthOrdered(termBuffer, frameOffset, frameLength);

            flags = 0;
            frameOffset += alignedLength;
            remaining -= bytesToWrite;
        }
        while (remaining > 0);
    }

    return resultingOffset;
}
 
Example 17
Source File: TermReader.java    From aeron with Apache License 2.0 4 votes vote down vote up
/**
 * Reads data from a term in a log buffer and updates a passed {@link Position} so progress is not lost in the
 * event of an exception.
 *
 * @param termBuffer         to be read for fragments.
 * @param termOffset         within the buffer that the read should begin.
 * @param handler            the handler for data that has been read
 * @param fragmentsLimit     limit the number of fragments read.
 * @param header             to be used for mapping over the header for a given fragment.
 * @param errorHandler       to be notified if an error occurs during the callback.
 * @param currentPosition    prior to reading further fragments
 * @param subscriberPosition to be updated after reading with new position
 * @return the number of fragments read
 */
public static int read(
    final UnsafeBuffer termBuffer,
    final int termOffset,
    final FragmentHandler handler,
    final int fragmentsLimit,
    final Header header,
    final ErrorHandler errorHandler,
    final long currentPosition,
    final Position subscriberPosition)
{
    int fragmentsRead = 0;
    int offset = termOffset;
    final int capacity = termBuffer.capacity();
    header.buffer(termBuffer);

    try
    {
        while (fragmentsRead < fragmentsLimit && offset < capacity)
        {
            final int frameLength = frameLengthVolatile(termBuffer, offset);
            if (frameLength <= 0)
            {
                break;
            }

            final int frameOffset = offset;
            offset += BitUtil.align(frameLength, FRAME_ALIGNMENT);

            if (!isPaddingFrame(termBuffer, frameOffset))
            {
                header.offset(frameOffset);
                handler.onFragment(termBuffer, frameOffset + HEADER_LENGTH, frameLength - HEADER_LENGTH, header);

                ++fragmentsRead;
            }
        }
    }
    catch (final Throwable t)
    {
        errorHandler.onError(t);
    }
    finally
    {
        final long newPosition = currentPosition + (offset - termOffset);
        if (newPosition > currentPosition)
        {
            subscriberPosition.setOrdered(newPosition);
        }
    }

    return fragmentsRead;
}
 
Example 18
Source File: TermReader.java    From aeron with Apache License 2.0 4 votes vote down vote up
/**
 * Reads data from a term in a log buffer.
 *
 * @param termBuffer     to be read for fragments.
 * @param termOffset     within the buffer that the read should begin.
 * @param handler        the handler for data that has been read
 * @param fragmentsLimit limit the number of fragments read.
 * @param header         to be used for mapping over the header for a given fragment.
 * @param errorHandler   to be notified if an error occurs during the callback.
 * @return the number of fragments read
 */
public static long read(
    final UnsafeBuffer termBuffer,
    final int termOffset,
    final FragmentHandler handler,
    final int fragmentsLimit,
    final Header header,
    final ErrorHandler errorHandler)
{
    int fragmentsRead = 0;
    int offset = termOffset;
    final int capacity = termBuffer.capacity();
    header.buffer(termBuffer);

    try
    {
        while (fragmentsRead < fragmentsLimit && offset < capacity)
        {
            final int frameLength = frameLengthVolatile(termBuffer, offset);
            if (frameLength <= 0)
            {
                break;
            }

            final int frameOffset = offset;
            offset += BitUtil.align(frameLength, FRAME_ALIGNMENT);

            if (!isPaddingFrame(termBuffer, frameOffset))
            {
                header.offset(frameOffset);
                handler.onFragment(termBuffer, frameOffset + HEADER_LENGTH, frameLength - HEADER_LENGTH, header);

                ++fragmentsRead;
            }
        }
    }
    catch (final Throwable t)
    {
        errorHandler.onError(t);
    }

    return pack(offset, fragmentsRead);
}
 
Example 19
Source File: ExclusiveTermAppender.java    From aeron with Apache License 2.0 4 votes vote down vote up
/**
 * 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 bufferOne             containing the first part of the message.
 * @param offsetOne             at which the first part of the message begins.
 * @param lengthOne             of the first part of the message.
 * @param bufferTwo             containing the second part of the message.
 * @param offsetTwo             at which the second part of the message begins.
 * @param lengthTwo             of the second part of the message.
 * @param reservedValueSupplier {@link ReservedValueSupplier} for the frame.
 * @return the resulting offset of the term after the append on success otherwise {@link #FAILED}.
 */
public int appendUnfragmentedMessage(
    final int termId,
    final int termOffset,
    final HeaderWriter header,
    final DirectBuffer bufferOne,
    final int offsetOne,
    final int lengthOne,
    final DirectBuffer bufferTwo,
    final int offsetTwo,
    final int lengthTwo,
    final ReservedValueSupplier reservedValueSupplier)
{
    final int frameLength = lengthOne + lengthTwo + HEADER_LENGTH;
    final int alignedLength = align(frameLength, FRAME_ALIGNMENT);
    final UnsafeBuffer termBuffer = this.termBuffer;
    final 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 + HEADER_LENGTH, bufferOne, offsetOne, lengthOne);
        termBuffer.putBytes(termOffset + HEADER_LENGTH + lengthOne, bufferTwo, offsetTwo, lengthTwo);

        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;
}
 
Example 20
Source File: FragmentedMessageTest.java    From aeron with Apache License 2.0 4 votes vote down vote up
@ParameterizedTest
@MethodSource("channels")
@Timeout(10)
public void shouldReceivePublishedMessage(final String channel)
{
    final FragmentAssembler assembler = new FragmentAssembler(mockFragmentHandler);

    try (Subscription subscription = aeron.addSubscription(channel, STREAM_ID);
        Publication publication = aeron.addPublication(channel, STREAM_ID))
    {
        final UnsafeBuffer srcBuffer = new UnsafeBuffer(new byte[driver.context().mtuLength() * 4]);
        final int offset = 0;
        final int length = srcBuffer.capacity() / 4;

        for (int i = 0; i < 4; i++)
        {
            srcBuffer.setMemory(i * length, length, (byte)(65 + i));
        }

        while (publication.offer(srcBuffer, offset, srcBuffer.capacity()) < 0L)
        {
            Tests.yield();
        }

        final int expectedFragmentsBecauseOfHeader = 5;
        int numFragments = 0;
        do
        {
            final int fragments = subscription.poll(assembler, FRAGMENT_COUNT_LIMIT);
            if (0 == fragments)
            {
                Tests.yield();
            }
            numFragments += fragments;
        }
        while (numFragments < expectedFragmentsBecauseOfHeader);

        final ArgumentCaptor<DirectBuffer> bufferArg = ArgumentCaptor.forClass(DirectBuffer.class);
        final ArgumentCaptor<Header> headerArg = ArgumentCaptor.forClass(Header.class);

        verify(mockFragmentHandler, times(1)).onFragment(
            bufferArg.capture(), eq(offset), eq(srcBuffer.capacity()), headerArg.capture());

        final DirectBuffer capturedBuffer = bufferArg.getValue();
        for (int i = 0; i < srcBuffer.capacity(); i++)
        {
            assertEquals(srcBuffer.getByte(i), capturedBuffer.getByte(i), "same at i=" + i);
        }

        assertEquals(END_FRAG_FLAG, headerArg.getValue().flags());
    }
}