private CommittedTransactionRepresentation readFromChannel( ReadableLogChannel channel ) throws IOException { LogEntryReader<ReadableLogChannel> logEntryReader = new VersionAwareLogEntryReader<>(); try ( PhysicalTransactionCursor<ReadableLogChannel> cursor = new PhysicalTransactionCursor<>( channel, logEntryReader ) ) { assertTrue( cursor.next() ); return cursor.get(); } }
@Test public void shouldCloseTheUnderlyingChannel() throws IOException { // when cursor.close(); // then verify( channel, times( 1 ) ).close(); }
ReversedSingleFileTransactionCursor( ReadAheadLogChannel channel, LogEntryReader<ReadableClosablePositionAwareChannel> logEntryReader, boolean failOnCorruptedLogFiles, ReversedTransactionCursorMonitor monitor ) throws IOException { this.channel = channel; this.failOnCorruptedLogFiles = failOnCorruptedLogFiles; this.monitor = monitor; // There's an assumption here: that the underlying channel can move in between calls and that the // transaction cursor will just happily read from the new position. this.transactionCursor = new PhysicalTransactionCursor<>( channel, logEntryReader ); this.offsets = sketchOutTransactionStartOffsets(); }
private int transactionCount() throws IOException { return aggregateLogData( version -> { int counter = 0; LogVersionBridge bridge = channel -> channel; LogVersionedStoreChannel versionedStoreChannel = files.openForVersion( version ); try ( ReadableLogChannel channel = new ReadAheadLogChannel( versionedStoreChannel, bridge, 1000 ) ) { try ( PhysicalTransactionCursor<ReadableLogChannel> physicalTransactionCursor = new PhysicalTransactionCursor<>( channel, new VersionAwareLogEntryReader<>() ) ) { while ( physicalTransactionCursor.next() ) { counter++; } } } return counter; } ); } }
@Before public void setup() throws IOException { cursor = new PhysicalTransactionCursor<>( channel, entryReader ); }
@Test public void shouldAppendSingleTransaction() throws Exception { // GIVEN when( logFile.getWriter() ).thenReturn( channel ); long txId = 15; when( transactionIdStore.nextCommittingTransactionId() ).thenReturn( txId ); TransactionAppender appender = life.add( createTransactionAppender() ); // WHEN TransactionRepresentation transaction = transaction( singleCreateNodeCommand( 0 ), new byte[]{1, 2, 5}, 2, 1, 12345, 4545, 12345 + 10 ); appender.append( new TransactionToApply( transaction ), logAppendEvent ); // THEN final LogEntryReader<ReadableLogChannel> logEntryReader = new VersionAwareLogEntryReader<>(); try ( PhysicalTransactionCursor<ReadableLogChannel> reader = new PhysicalTransactionCursor<>( channel, logEntryReader ) ) { reader.next(); TransactionRepresentation tx = reader.get().getTransactionRepresentation(); assertArrayEquals( transaction.additionalHeader(), tx.additionalHeader() ); assertEquals( transaction.getMasterId(), tx.getMasterId() ); assertEquals( transaction.getAuthorId(), tx.getAuthorId() ); assertEquals( transaction.getTimeStarted(), tx.getTimeStarted() ); assertEquals( transaction.getTimeCommitted(), tx.getTimeCommitted() ); assertEquals( transaction.getLatestCommittedTxWhenStarted(), tx.getLatestCommittedTxWhenStarted() ); } }
@Test public void shouldCallTheVisitorWithTheFoundTransaction() throws IOException { // given when( entryReader.readLogEntry( channel ) ).thenReturn( A_START_ENTRY, A_COMMAND_ENTRY, A_COMMIT_ENTRY ); // when cursor.next(); // then PhysicalTransactionRepresentation txRepresentation = new PhysicalTransactionRepresentation( singletonList( A_COMMAND_ENTRY.getCommand() ) ); assertEquals( new CommittedTransactionRepresentation( A_START_ENTRY, txRepresentation, A_COMMIT_ENTRY ), cursor.get() ); }
@Override public TransactionCursor getTransactions( LogPosition position ) throws IOException { return new PhysicalTransactionCursor<>( logFile.getReader( position ), new VersionAwareLogEntryReader<>() ); }
new PhysicalTransactionCursor<>( channel, logEntryReader ) ) reader.next(); TransactionRepresentation result = reader.get().getTransactionRepresentation(); assertArrayEquals( additionalHeader, result.additionalHeader() ); assertEquals( masterId, result.getMasterId() );
@Test public void shouldSkipCheckPoints() throws IOException { // given when( entryReader.readLogEntry( channel ) ).thenReturn( A_CHECK_POINT_ENTRY, A_START_ENTRY, A_COMMAND_ENTRY, A_COMMIT_ENTRY, A_CHECK_POINT_ENTRY ); // when cursor.next(); // then PhysicalTransactionRepresentation txRepresentation = new PhysicalTransactionRepresentation( singletonList( A_COMMAND_ENTRY.getCommand() ) ); assertEquals( new CommittedTransactionRepresentation( A_START_ENTRY, txRepresentation, A_COMMIT_ENTRY ), cursor.get() ); } }
return new PhysicalTransactionCursor<>( channel, logEntryReader ); logFile.accept( transactionPositionLocator, headerVisitor.getLogPosition() ); LogPosition position = transactionPositionLocator.getAndCacheFoundLogPosition( transactionMetadataCache ); return new PhysicalTransactionCursor<>( logFile.getReader( position ), logEntryReader );
@Override protected void decode( ChannelHandlerContext ctx, ByteBuf msg, List<Object> out ) throws Exception { NetworkReadableClosableChannelNetty4 logChannel = new NetworkReadableClosableChannelNetty4( msg ); StoreId storeId = StoreIdMarshal.INSTANCE.unmarshal( logChannel ); LogEntryReader<NetworkReadableClosableChannelNetty4> reader = new VersionAwareLogEntryReader<>( new RecordStorageCommandReaderFactory() ); PhysicalTransactionCursor<NetworkReadableClosableChannelNetty4> transactionCursor = new PhysicalTransactionCursor<>( logChannel, reader ); transactionCursor.next(); CommittedTransactionRepresentation tx = transactionCursor.get(); if ( tx != null ) { out.add( new TxPullResponse( storeId, tx ) ); } } }
return eagerlyReverse( new PhysicalTransactionCursor<>( channel, logEntryReader ) ); }; return new ReversedMultiFileTransactionCursor( factory, highestVersion, backToPosition );
@Override protected void decode( ChannelHandlerContext ctx, ByteBuf msg, List<Object> out ) throws Exception { NetworkReadableClosableChannelNetty4 logChannel = new NetworkReadableClosableChannelNetty4( msg ); StoreId storeId = StoreIdMarshal.INSTANCE.unmarshal( logChannel ); LogEntryReader<NetworkReadableClosableChannelNetty4> reader = new VersionAwareLogEntryReader<>( new RecordStorageCommandReaderFactory(), InvalidLogEntryHandler.STRICT ); PhysicalTransactionCursor<NetworkReadableClosableChannelNetty4> transactionCursor = new PhysicalTransactionCursor<>( logChannel, reader ); transactionCursor.next(); CommittedTransactionRepresentation tx = transactionCursor.get(); if ( tx != null ) { out.add( new TxPullResponse( storeId, tx ) ); } } }
ReversedSingleFileTransactionCursor( ReadAheadLogChannel channel, LogEntryReader<ReadableClosablePositionAwareChannel> logEntryReader, boolean failOnCorruptedLogFiles, ReversedTransactionCursorMonitor monitor ) throws IOException { this.channel = channel; this.failOnCorruptedLogFiles = failOnCorruptedLogFiles; this.monitor = monitor; // There's an assumption here: that the underlying channel can move in between calls and that the // transaction cursor will just happily read from the new position. this.transactionCursor = new PhysicalTransactionCursor<>( channel, logEntryReader ); this.offsets = sketchOutTransactionStartOffsets(); }
new PhysicalTransactionCursor<>( channel, entryReader ) ) while ( cursor.next() && !visitor.visit( cursor.get() ) )
@Override public TransactionCursor getTransactions( LogPosition position ) throws IOException { return new PhysicalTransactionCursor<>( logFile.getReader( position ), new VersionAwareLogEntryReader<>() ); }
return new PhysicalTransactionCursor<>( channel, logEntryReader ); logFile.accept( transactionPositionLocator, headerVisitor.getLogPosition() ); LogPosition position = transactionPositionLocator.getAndCacheFoundLogPosition( transactionMetadataCache ); return new PhysicalTransactionCursor<>( logFile.getReader( position ), logEntryReader );