/** * Get a wrapper around the default frame header from the log meta data. * * @param metadataBuffer containing the raw bytes for the default frame header. * @return a buffer wrapping the raw bytes. */ public static UnsafeBuffer defaultFrameHeader(final UnsafeBuffer metadataBuffer) { return new UnsafeBuffer(metadataBuffer, LOG_DEFAULT_FRAME_HEADER_OFFSET, HEADER_LENGTH); }
/** * The current capacity of the buffer. * * @return the current capacity of the buffer. */ public int capacity() { return buffer.capacity(); }
/** * 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)); } } }
/** * Commit the message to the log buffer so that is it available to subscribers. */ public final void commit() { int frameLength = buffer.capacity(); if (ByteOrder.nativeOrder() != LITTLE_ENDIAN) { frameLength = Integer.reverseBytes(frameLength); } buffer.putIntOrdered(FRAME_LENGTH_FIELD_OFFSET, frameLength); }
private void resize(final int newCapacity) { if (isDirect) { final ByteBuffer byteBuffer = ByteBuffer.allocateDirect(newCapacity); byteBuffer.order(ByteOrder.LITTLE_ENDIAN); buffer.getBytes(0, byteBuffer, 0, limit); buffer.wrap(byteBuffer); } else { buffer.wrap(Arrays.copyOf(buffer.byteArray(), newCapacity)); } }
@Test public void shouldFillSingleGap() { final int frameLength = 50; final int alignedFrameLength = BitUtil.align(frameLength, FRAME_ALIGNMENT); final int srcOffset = 0; final int tail = alignedFrameLength; final int termOffset = tail; final UnsafeBuffer packet = new UnsafeBuffer(ByteBuffer.allocateDirect(alignedFrameLength)); TermRebuilder.insert(termBuffer, termOffset, packet, alignedFrameLength); verify(termBuffer).putBytes( tail + HEADER_LENGTH, packet, srcOffset + HEADER_LENGTH, alignedFrameLength - HEADER_LENGTH); }
@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)); }
@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()); }
@Test public void shouldRejectWriteWhenInsufficientSpace() { final int length = 200; final long head = 0L; final long tail = head + (CAPACITY - align(length - ALIGNMENT, ALIGNMENT)); when(buffer.getLongVolatile(HEAD_COUNTER_INDEX)).thenReturn(head); when(buffer.getLong(TAIL_COUNTER_INDEX)).thenReturn(tail); final UnsafeBuffer srcBuffer = new UnsafeBuffer(new byte[1024]); final int srcIndex = 0; assertFalse(ringBuffer.write(MSG_TYPE_ID, srcBuffer, srcIndex, length)); verify(buffer, never()).putBytes(anyInt(), eq(srcBuffer), anyInt(), anyInt()); verify(buffer, never()).putLong(anyInt(), anyInt()); verify(buffer, never()).putLongOrdered(anyInt(), anyInt()); verify(buffer, never()).putIntOrdered(anyInt(), anyInt()); }
@Test public void shouldInsertLastFrameIntoBuffer() { final int frameLength = BitUtil.align(256, FRAME_ALIGNMENT); final int srcOffset = 0; final int tail = TERM_BUFFER_CAPACITY - frameLength; final int termOffset = tail; final UnsafeBuffer packet = new UnsafeBuffer(ByteBuffer.allocateDirect(frameLength)); packet.putShort(typeOffset(srcOffset), (short)PADDING_FRAME_TYPE, LITTLE_ENDIAN); packet.putInt(srcOffset, frameLength, LITTLE_ENDIAN); TermRebuilder.insert(termBuffer, termOffset, packet, frameLength); verify(termBuffer).putBytes( tail + HEADER_LENGTH, packet, srcOffset + HEADER_LENGTH, frameLength - HEADER_LENGTH); }
@Test public void shouldScanForwardForNextNonCommittedMessage() { final int messageLength = HEADER_LENGTH * 4; final int termOffset = 0; final int tailOffset = messageLength * 2; when(mockTermBuffer.getIntVolatile(messageLength)).thenReturn(-messageLength); assertThat(TermUnblocker.unblock( mockLogMetaDataBuffer, mockTermBuffer, termOffset, tailOffset, TERM_ID), is(UNBLOCKED)); final InOrder inOrder = inOrder(mockTermBuffer); inOrder.verify(mockTermBuffer).putShort(typeOffset(termOffset), (short)HDR_TYPE_PAD, LITTLE_ENDIAN); inOrder.verify(mockTermBuffer).putInt(termOffsetOffset(termOffset), termOffset, LITTLE_ENDIAN); inOrder.verify(mockTermBuffer).putIntOrdered(termOffset, messageLength); }
@Test public void shouldRejectWriteWhenBufferFull() { final int length = 8; final long head = 0L; final long tail = head + CAPACITY; when(buffer.getLongVolatile(HEAD_COUNTER_INDEX)).thenReturn(head); when(buffer.getLong(TAIL_COUNTER_INDEX)).thenReturn(tail); final UnsafeBuffer srcBuffer = new UnsafeBuffer(new byte[1024]); final int srcIndex = 0; assertFalse(ringBuffer.write(MSG_TYPE_ID, srcBuffer, srcIndex, length)); verify(buffer, never()).putLongOrdered(anyInt(), anyInt()); }
@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)); }
/** * Get the value of the MTU length used for this log. * * @param metadataBuffer containing the meta data. * @return the value of the MTU length used for this log. */ public static int mtuLength(final UnsafeBuffer metadataBuffer) { return metadataBuffer.getInt(LOG_MTU_LENGTH_OFFSET); }
/** * Wrap a region of an underlying log buffer so can can represent a claimed space for use by a publisher. * * @param buffer to be wrapped. * @param offset at which the claimed region begins including space for the header. * @param length length of the underlying claimed region including space for the header. */ public final void wrap(final AtomicBuffer buffer, final int offset, final int length) { this.buffer.wrap(buffer, offset, length); }
@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); } }
/** * Set the page size used for this log. * * @param metadataBuffer containing the meta data. * @param pageSize value to be set. */ public static void pageSize(final UnsafeBuffer metadataBuffer, final int pageSize) { metadataBuffer.putInt(LOG_PAGE_SIZE_OFFSET, pageSize); }
@Test public void shouldReadFirstMessage() { final int offset = 0; final int limit = termBuffer.capacity(); final int messageLength = 50; final int alignedMessageLength = BitUtil.align(messageLength, FRAME_ALIGNMENT); when(termBuffer.getIntVolatile(lengthOffset(offset))).thenReturn(messageLength); when(termBuffer.getShort(typeOffset(offset))).thenReturn((short)HDR_TYPE_DATA); final int newOffset = TermBlockScanner.scan(termBuffer, offset, limit); assertThat(newOffset, is(alignedMessageLength)); }
private void captureEntriesFromBuffer( final ByteBuffer byteBuffer, final UnsafeBuffer buffer, final ArrayList<Entry> entries) { for (int i = 0, length = byteBuffer.limit(); i < length; i += ENTRY_LENGTH) { final int entryType = buffer.getInt(i + ENTRY_TYPE_OFFSET); if (NULL_VALUE != entryType) { final Entry entry = new Entry( buffer.getLong(i + RECORDING_ID_OFFSET, LITTLE_ENDIAN), buffer.getLong(i + LEADERSHIP_TERM_ID_OFFSET, LITTLE_ENDIAN), buffer.getLong(i + TERM_BASE_LOG_POSITION_OFFSET, LITTLE_ENDIAN), buffer.getLong(i + LOG_POSITION_OFFSET, LITTLE_ENDIAN), buffer.getLong(i + TIMESTAMP_OFFSET, LITTLE_ENDIAN), buffer.getInt(i + SERVICE_ID_OFFSET, LITTLE_ENDIAN), entryType, nextEntryIndex); entries.add(entry); if (ENTRY_TYPE_TERM == entryType) { indexByLeadershipTermIdMap.put(entry.leadershipTermId, nextEntryIndex); } } ++nextEntryIndex; } }
/** * Store the default frame header to the log meta data buffer. * * @param metadataBuffer into which the default headers should be stored. * @param defaultHeader to be stored. * @throws IllegalArgumentException if the defaultHeader larger than {@link #LOG_DEFAULT_FRAME_HEADER_MAX_LENGTH} */ public static void storeDefaultFrameHeader(final UnsafeBuffer metadataBuffer, final DirectBuffer defaultHeader) { if (defaultHeader.capacity() != HEADER_LENGTH) { throw new IllegalArgumentException( "Default header length not equal to HEADER_LENGTH: length=" + defaultHeader.capacity()); } metadataBuffer.putInt(LOG_DEFAULT_FRAME_HEADER_LENGTH_OFFSET, HEADER_LENGTH); metadataBuffer.putBytes(LOG_DEFAULT_FRAME_HEADER_OFFSET, defaultHeader, 0, HEADER_LENGTH); }