/** * Set the correlation ID used for this log relating to the command which created it. * * @param metadataBuffer containing the meta data. * @param id value to be set. */ public static void correlationId(final UnsafeBuffer metadataBuffer, final long id) { metadataBuffer.putLong(LOG_CORRELATION_ID_OFFSET, id); }
public void extendRecording(final long recordingId, final long controlSessionId, final long correlationId) { final int offset = recordingDescriptorOffset(recordingId) + RecordingDescriptorHeaderDecoder.BLOCK_LENGTH; final long stopPosition = nativeOrder() == BYTE_ORDER ? NULL_POSITION : Long.reverseBytes(NULL_POSITION); fieldAccessBuffer.putLong(offset + controlSessionIdEncodingOffset(), controlSessionId); fieldAccessBuffer.putLong(offset + correlationIdEncodingOffset(), correlationId); fieldAccessBuffer.putLong(offset + stopTimestampEncodingOffset(), NULL_TIMESTAMP); fieldAccessBuffer.putLongVolatile(offset + stopPositionEncodingOffset(), stopPosition); forceWrites(catalogChannel, forceWrites, forceMetadata); }
/** * Insert a packet of frames into the log at the appropriate termOffset as indicated by the term termOffset header. * <p> * If the packet has already been inserted then this is a noop. * * @param termBuffer into which the packet should be inserted. * @param termOffset in the term at which the packet should be inserted. * @param packet containing a sequence of frames. * @param length of the packet of frames in bytes. */ public static void insert( final UnsafeBuffer termBuffer, final int termOffset, final UnsafeBuffer packet, final int length) { if (0 == termBuffer.getInt(termOffset)) { termBuffer.putBytes(termOffset + HEADER_LENGTH, packet, HEADER_LENGTH, length - HEADER_LENGTH); termBuffer.putLong(termOffset + 24, packet.getLong(24)); termBuffer.putLong(termOffset + 16, packet.getLong(16)); termBuffer.putLong(termOffset + 8, packet.getLong(8)); termBuffer.putLongOrdered(termOffset, packet.getLong(0)); } } }
/** * Set the raw value of the tail for the given partition. * * @param metadataBuffer containing the tail counters. * @param partitionIndex for the tail counter. * @param rawTail to be stored */ public static void rawTail(final UnsafeBuffer metadataBuffer, final int partitionIndex, final long rawTail) { metadataBuffer.putLong(TERM_TAIL_COUNTERS_OFFSET + (SIZE_OF_LONG * partitionIndex), rawTail); }
@Test public void shouldInsertIntoEmptyBuffer() { final UnsafeBuffer packet = new UnsafeBuffer(ByteBuffer.allocateDirect(256)); final int termOffset = 0; final int srcOffset = 0; final int length = 256; packet.putInt(srcOffset, length, LITTLE_ENDIAN); TermRebuilder.insert(termBuffer, termOffset, packet, length); final InOrder inOrder = inOrder(termBuffer); inOrder.verify(termBuffer).putBytes( termOffset + HEADER_LENGTH, packet, srcOffset + HEADER_LENGTH, length - HEADER_LENGTH); inOrder.verify(termBuffer).putLong(termOffset + 24, packet.getLong(24)); inOrder.verify(termBuffer).putLong(termOffset + 16, packet.getLong(16)); inOrder.verify(termBuffer).putLong(termOffset + 8, packet.getLong(8)); inOrder.verify(termBuffer).putLongOrdered(termOffset, packet.getLong(0)); }
public void recordingStopped(final long recordingId, final long position, final long timestamp) { final int offset = recordingDescriptorOffset(recordingId) + RecordingDescriptorHeaderDecoder.BLOCK_LENGTH; final long stopPosition = nativeOrder() == BYTE_ORDER ? position : Long.reverseBytes(position); fieldAccessBuffer.putLong(offset + stopTimestampEncodingOffset(), timestamp, BYTE_ORDER); fieldAccessBuffer.putLongVolatile(offset + stopPositionEncodingOffset(), stopPosition); forceWrites(catalogChannel, forceWrites, forceMetadata); }
/** * Write the provided value into the reserved space at the end of the data frame header. * <p> * Note: The value will be written in {@link ByteOrder#LITTLE_ENDIAN} format. * * @param value to be stored in the reserve space at the end of a data frame header. * @return this for fluent API semantics. * @see io.aeron.protocol.DataHeaderFlyweight */ public ExclusiveBufferClaim reservedValue(final long value) { buffer.putLong(RESERVED_VALUE_OFFSET, value, LITTLE_ENDIAN); return this; }
/** * Write the provided value into the reserved space at the end of the data frame header. * <p> * Note: The value will be written in {@link ByteOrder#LITTLE_ENDIAN} format. * * @param value to be stored in the reserve space at the end of a data frame header. * @return this for fluent API semantics. * @see io.aeron.protocol.DataHeaderFlyweight */ public BufferClaim reservedValue(final long value) { buffer.putLong(RESERVED_VALUE_OFFSET, value, LITTLE_ENDIAN); return this; }
/** * Set the initial value for the termId in the upper bits of the tail counter. * * @param metadataBuffer contain the tail counter. * @param partitionIndex to be initialised. * @param termId to be set. */ public static void initialiseTailWithTermId( final UnsafeBuffer metadataBuffer, final int partitionIndex, final int termId) { metadataBuffer.putLong(TERM_TAIL_COUNTERS_OFFSET + (partitionIndex * SIZE_OF_LONG), packTail(termId, 0)); }
private void commitEntryValue(final int entryIndex, final long value, final int fieldOffset) { buffer.putLong(0, value, LITTLE_ENDIAN); byteBuffer.limit(SIZE_OF_LONG).position(0); final long filePosition = (entryIndex * (long)ENTRY_LENGTH) + fieldOffset; try { if (SIZE_OF_LONG != fileChannel.write(byteBuffer, filePosition)) { throw new ClusterException("failed to write field atomically"); } } catch (final Exception ex) { LangUtil.rethrowUnchecked(ex); } }
public static void fillMetaData( final UnsafeBuffer cncMetaDataBuffer, final int toDriverBufferLength, final int toClientsBufferLength, final int counterMetaDataBufferLength, final int counterValuesBufferLength, final long clientLivenessTimeout, final int errorLogBufferLength, final long startTimestamp, final long pid) { cncMetaDataBuffer.putInt(toDriverBufferLengthOffset(0), toDriverBufferLength); cncMetaDataBuffer.putInt(toClientsBufferLengthOffset(0), toClientsBufferLength); cncMetaDataBuffer.putInt(countersMetaDataBufferLengthOffset(0), counterMetaDataBufferLength); cncMetaDataBuffer.putInt(countersValuesBufferLengthOffset(0), counterValuesBufferLength); cncMetaDataBuffer.putInt(errorLogBufferLengthOffset(0), errorLogBufferLength); cncMetaDataBuffer.putLong(clientLivenessTimeoutOffset(0), clientLivenessTimeout); cncMetaDataBuffer.putLong(startTimestampOffset(0), startTimestamp); cncMetaDataBuffer.putLong(pidOffset(0), pid); }
@Test public void sharedBuffer() { final ByteBuffer bb = ByteBuffer.allocateDirect(1024); final UnsafeBuffer ub1 = new UnsafeBuffer(bb, 0, 512); final UnsafeBuffer ub2 = new UnsafeBuffer(bb, 512, 512); ub1.putLong(INDEX, LONG_VALUE); ub2.putLong(INDEX, 9876543210L); assertThat(ub1.getLong(INDEX), is(LONG_VALUE)); }
@Test public void shouldFragmentMessageOverTwoFrames() { final int msgLength = MAX_PAYLOAD_LENGTH + 1; final int headerLength = DEFAULT_HEADER.capacity(); final int frameLength = headerLength + 1; final int requiredCapacity = align(headerLength + 1, FRAME_ALIGNMENT) + MAX_FRAME_LENGTH; final UnsafeBuffer buffer = new UnsafeBuffer(new byte[msgLength]); int tail = 0; logMetaDataBuffer.putLong(TERM_TAIL_COUNTER_OFFSET, packTail(TERM_ID, tail)); assertThat(termAppender.appendFragmentedMessage( headerWriter, buffer, 0, msgLength, MAX_PAYLOAD_LENGTH, RVS, TERM_ID), is(requiredCapacity)); assertThat(rawTailVolatile(logMetaDataBuffer, PARTITION_INDEX), is(packTail(TERM_ID, tail + requiredCapacity))); final InOrder inOrder = inOrder(termBuffer, headerWriter); inOrder.verify(headerWriter, times(1)).write(termBuffer, tail, MAX_FRAME_LENGTH, TERM_ID); inOrder.verify(termBuffer, times(1)).putBytes(tail + headerLength, buffer, 0, MAX_PAYLOAD_LENGTH); inOrder.verify(termBuffer, times(1)).putByte(flagsOffset(tail), BEGIN_FRAG_FLAG); inOrder.verify(termBuffer, times(1)).putLong(tail + RESERVED_VALUE_OFFSET, RV, LITTLE_ENDIAN); inOrder.verify(termBuffer, times(1)).putIntOrdered(tail, MAX_FRAME_LENGTH); tail = MAX_FRAME_LENGTH; inOrder.verify(headerWriter, times(1)).write(termBuffer, tail, frameLength, TERM_ID); inOrder.verify(termBuffer, times(1)).putBytes(tail + headerLength, buffer, MAX_PAYLOAD_LENGTH, 1); inOrder.verify(termBuffer, times(1)).putByte(flagsOffset(tail), END_FRAG_FLAG); inOrder.verify(termBuffer, times(1)).putLong(tail + RESERVED_VALUE_OFFSET, RV, LITTLE_ENDIAN); inOrder.verify(termBuffer, times(1)).putIntOrdered(tail, frameLength); }
@Test public void shouldAppendFrameToEmptyLog() { final int headerLength = DEFAULT_HEADER.capacity(); final UnsafeBuffer buffer = new UnsafeBuffer(new byte[128]); final int msgLength = 20; 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)); assertThat(termAppender.appendUnfragmentedMessage(headerWriter, buffer, 0, msgLength, RVS, TERM_ID), is(alignedFrameLength)); assertThat(rawTailVolatile(logMetaDataBuffer, PARTITION_INDEX), is(packTail(TERM_ID, tail + alignedFrameLength))); final InOrder inOrder = inOrder(termBuffer, headerWriter); inOrder.verify(headerWriter, times(1)).write(termBuffer, tail, frameLength, TERM_ID); inOrder.verify(termBuffer, times(1)).putBytes(headerLength, buffer, 0, msgLength); inOrder.verify(termBuffer, times(1)).putLong(tail + RESERVED_VALUE_OFFSET, RV, LITTLE_ENDIAN); inOrder.verify(termBuffer, times(1)).putIntOrdered(tail, frameLength); }
@Test(expected = AeronException.class) public void shouldDetectInvalidTerm() { final int length = 128; final int srcOffset = 0; final UnsafeBuffer buffer = new UnsafeBuffer(new byte[length]); logMetaDataBuffer.putLong(TERM_TAIL_COUNTER_OFFSET, packTail(TERM_ID + 1, 0)); termAppender.appendUnfragmentedMessage(headerWriter, buffer, srcOffset, length, RVS, TERM_ID); } }
@Test public void shouldPadLogWhenAppendingWithInsufficientRemainingCapacity() { final int msgLength = 120; final int headerLength = DEFAULT_HEADER.capacity(); final int requiredFrameSize = align(headerLength + msgLength, FRAME_ALIGNMENT); final int tailValue = TERM_BUFFER_LENGTH - align(msgLength, FRAME_ALIGNMENT); final UnsafeBuffer buffer = new UnsafeBuffer(new byte[128]); final int frameLength = TERM_BUFFER_LENGTH - tailValue; logMetaDataBuffer.putLong(TERM_TAIL_COUNTER_OFFSET, packTail(TERM_ID, tailValue)); assertThat(termAppender.appendUnfragmentedMessage(headerWriter, buffer, 0, msgLength, RVS, TERM_ID), is(FAILED)); assertThat(rawTailVolatile(logMetaDataBuffer, PARTITION_INDEX), is(packTail(TERM_ID, tailValue + requiredFrameSize))); final InOrder inOrder = inOrder(termBuffer, headerWriter); inOrder.verify(headerWriter, times(1)).write(termBuffer, tailValue, frameLength, TERM_ID); inOrder.verify(termBuffer, times(1)).putShort(typeOffset(tailValue), (short)PADDING_FRAME_TYPE, LITTLE_ENDIAN); inOrder.verify(termBuffer, times(1)).putIntOrdered(tailValue, frameLength); }
/** * Return an initialised default Data Frame Header. * * @param sessionId for the header * @param streamId for the header * @param termId for the header * @return byte array containing the header */ public static UnsafeBuffer createDefaultHeader(final int sessionId, final int streamId, final int termId) { final UnsafeBuffer buffer = new UnsafeBuffer( BufferUtil.allocateDirectAligned(HEADER_LENGTH, CACHE_LINE_LENGTH)); buffer.putByte(VERSION_FIELD_OFFSET, CURRENT_VERSION); buffer.putByte(FLAGS_FIELD_OFFSET, (byte)BEGIN_AND_END_FLAGS); buffer.putShort(TYPE_FIELD_OFFSET, (short)HDR_TYPE_DATA, LITTLE_ENDIAN); buffer.putInt(SESSION_ID_FIELD_OFFSET, sessionId, LITTLE_ENDIAN); buffer.putInt(STREAM_ID_FIELD_OFFSET, streamId, LITTLE_ENDIAN); buffer.putInt(TERM_ID_FIELD_OFFSET, termId, LITTLE_ENDIAN); buffer.putLong(RESERVED_VALUE_OFFSET, DEFAULT_RESERVE_VALUE); return buffer; }
@Test public void shouldUnblockWhenPositionHasNonCommittedMessageAndTailPastEndOfTerm() { final int messageLength = HEADER_LENGTH * 4; final int blockedOffset = TERM_LENGTH - messageLength; final long blockedPosition = computePosition(TERM_ID_1, blockedOffset, positionBitsToShift, TERM_ID_1); final int activeIndex = indexByPosition(blockedPosition, positionBitsToShift); when(termBuffers[activeIndex].getIntVolatile(blockedOffset)).thenReturn(0); logMetaDataBuffer.putLong(TERM_TAIL_COUNTER_OFFSET, pack(TERM_ID_1, TERM_LENGTH + HEADER_LENGTH)); assertTrue(LogBufferUnblocker.unblock(termBuffers, logMetaDataBuffer, blockedPosition, TERM_LENGTH)); final long rawTail = rawTailVolatile(logMetaDataBuffer); final int termId = termId(rawTail); assertThat(computePosition(termId, 0, positionBitsToShift, TERM_ID_1), is(blockedPosition + messageLength)); verify(logMetaDataBuffer).compareAndSetInt(LOG_ACTIVE_TERM_COUNT_OFFSET, 0, 1); }
@Test public void shouldClaimRegionForZeroCopyEncoding() { final int headerLength = DEFAULT_HEADER.capacity(); final int msgLength = 20; final int frameLength = msgLength + headerLength; final int alignedFrameLength = align(frameLength, FRAME_ALIGNMENT); final int tail = 0; final BufferClaim bufferClaim = new BufferClaim(); logMetaDataBuffer.putLong(TERM_TAIL_COUNTER_OFFSET, packTail(TERM_ID, tail)); assertThat(termAppender.claim(headerWriter, msgLength, bufferClaim, TERM_ID), is(alignedFrameLength)); assertThat(bufferClaim.offset(), is(tail + headerLength)); assertThat(bufferClaim.length(), is(msgLength)); assertThat(rawTailVolatile(logMetaDataBuffer, PARTITION_INDEX), is(packTail(TERM_ID, tail + alignedFrameLength))); // Map flyweight or encode to buffer directly then call commit() when done bufferClaim.commit(); final InOrder inOrder = inOrder(headerWriter); inOrder.verify(headerWriter, times(1)).write(termBuffer, tail, frameLength, TERM_ID); }
@Test public void shouldPutBytesFromDirectBuffer() { buffer = new MappedResizeableBuffer(channel, 0, 100); final long value = 0x5555555555555555L; final UnsafeBuffer onHeapDirectBuffer = new UnsafeBuffer(new byte[24]); onHeapDirectBuffer.putLong(16, value); buffer.putBytes(24, onHeapDirectBuffer, 16, 8); assertThat(buffer.getLong(24), is(value)); final UnsafeBuffer offHeapDirectBuffer = new UnsafeBuffer(buffer.addressOffset(), (int)buffer.capacity()); buffer.putBytes(96, offHeapDirectBuffer, 24, 4); assertThat(buffer.getInt(96), is((int)value)); }