@Test public void shouldReturnUnspecifiedWhenAskedTo() { // given final LogPositionMarker marker = new LogPositionMarker(); // when marker.mark( 1, 2 ); marker.unspecified(); final LogPosition logPosition = marker.newPosition(); // given assertEquals(LogPosition.UNSPECIFIED, logPosition); } }
/** * Reading {@link LogEntry log entries} may have the source move over physically multiple log files. * This accessor returns the log version of the most recent call to {@link #next()}. * * @return the log version of the most recent {@link LogEntry} returned from {@link #next(). */ public long getCurrentLogVersion() throws IOException { channel.getCurrentPosition( position ); return position.getLogVersion(); } }
protected IOException unknownCommandType( byte commandType, ReadableChannel channel ) throws IOException { String message = "Unknown command type[" + commandType + "]"; if ( channel instanceof PositionAwareChannel ) { PositionAwareChannel logChannel = (PositionAwareChannel) channel; LogPositionMarker position = new LogPositionMarker(); logChannel.getCurrentPosition( position ); message += " near " + position.newPosition(); } return new IOException( message ); } }
@Test public void shouldReturnTheMarkedPosition() { // given final LogPositionMarker marker = new LogPositionMarker(); // when marker.mark( 1, 2 ); final LogPosition logPosition = marker.newPosition(); // given assertEquals(new LogPosition( 1, 2 ), logPosition); }
LogPositionMarker positionMarker = new LogPositionMarker(); long skipped = 0; while ( true ) LogPosition position = positionMarker.newPosition(); e = withMessage( e, e.getMessage() + ". At position " + position + " and entry version " + version ); invalidLogEntryHandler.handleInvalidEntry( e, position ) ) ((PositionableChannel)channel).setCurrentPosition( positionMarker.getByteOffset() + 1 ); skipped++; continue;
@Test public void shouldTruncateLogAfterSinglePartialTransaction() throws Exception { // GIVEN File file = logFiles.getLogFileForVersion( logVersion ); final LogPositionMarker marker = new LogPositionMarker(); writeSomeData( file, pair -> { LogEntryWriter writer = pair.first(); Consumer<LogPositionMarker> consumer = pair.other(); // incomplete tx consumer.accept( marker ); // <-- marker has the last good position writer.writeStartEntry( 0, 1, 5L, 4L, new byte[0] ); return true; } ); // WHEN boolean recoveryRequired = recover( storeDir, logFiles ); // THEN assertTrue( recoveryRequired ); assertEquals( marker.getByteOffset(), file.length() ); }
@Override public LogPositionMarker getCurrentPosition( LogPositionMarker positionMarker ) { positionMarker.unspecified(); return positionMarker; }
@Override public LogPositionMarker getCurrentPosition( LogPositionMarker positionMarker ) { positionMarker.mark( 0, buffer.position() ); return positionMarker; } }
/** * @return last known good position, which is a {@link LogPosition} after a {@link CheckPoint} or * a {@link LogEntryCommit}. */ @Override public LogPosition position() { return lastGoodPositionMarker.newPosition(); } }
@Test public void shouldReturnUnspecifiedIfNothingHasBeenMarked() { // given final LogPositionMarker marker = new LogPositionMarker(); // when final LogPosition logPosition = marker.newPosition(); // given assertEquals(LogPosition.UNSPECIFIED, logPosition); }
LogPositionMarker positionMarker = new LogPositionMarker(); long skipped = 0; while ( true ) LogPosition position = positionMarker.newPosition(); e = withMessage( e, e.getMessage() + ". At position " + position + " and entry version " + version ); invalidLogEntryHandler.handleInvalidEntry( e, position ) ) ((PositionableChannel)channel).setCurrentPosition( positionMarker.getByteOffset() + 1 ); skipped++; continue;
@Test public void shouldTruncateLogAfterLastCompleteTransactionAfterSuccessfulRecovery() throws Exception { // GIVEN File file = logFiles.getLogFileForVersion( logVersion ); final LogPositionMarker marker = new LogPositionMarker(); writeSomeData( file, pair -> { LogEntryWriter writer = pair.first(); Consumer<LogPositionMarker> consumer = pair.other(); // last committed tx writer.writeStartEntry( 0, 1, 2L, 3L, new byte[0] ); writer.writeCommitEntry( 4L, 5L ); // incomplete tx consumer.accept( marker ); // <-- marker has the last good position writer.writeStartEntry( 0, 1, 5L, 4L, new byte[0] ); return true; } ); // WHEN boolean recoveryRequired = recover( storeDir, logFiles ); // THEN assertTrue( recoveryRequired ); assertEquals( marker.getByteOffset(), file.length() ); }
@Override public LogPositionMarker getCurrentPosition( LogPositionMarker positionMarker ) { positionMarker.unspecified(); return positionMarker; }
@Override public LogPositionMarker getCurrentPosition( LogPositionMarker positionMarker ) throws IOException { positionMarker.mark( channel.getVersion(), position() ); return positionMarker; }
LogPosition logPositionBeforeCommit = writer.getCurrentPosition( positionMarker ).newPosition(); transactionLogWriter.append( transaction, transactionId ); LogPosition logPositionAfterCommit = writer.getCurrentPosition( positionMarker ).newPosition();
@Test public void shouldSeeCorrectPositionEvenBeforeEmptyingDataIntoChannel() throws Exception { // GIVEN final File file = new File( directory.directory(), "file" ); StoreChannel storeChannel = fileSystemRule.get().open( file, OpenMode.READ_WRITE ); PhysicalLogVersionedStoreChannel versionedStoreChannel = new PhysicalLogVersionedStoreChannel( storeChannel, 1, (byte) -1 /* ignored */ ); PositionAwarePhysicalFlushableChannel channel = new PositionAwarePhysicalFlushableChannel( versionedStoreChannel ); LogPositionMarker positionMarker = new LogPositionMarker(); LogPosition initialPosition = channel.getCurrentPosition( positionMarker ).newPosition(); // WHEN channel.putLong( 67 ); channel.putInt( 1234 ); LogPosition positionAfterSomeData = channel.getCurrentPosition( positionMarker ).newPosition(); // THEN assertEquals( 12, positionAfterSomeData.getByteOffset() - initialPosition.getByteOffset() ); channel.close(); }
@Test public void doNotTruncateCheckpointsAfterLastTransaction() throws IOException { File file = logFiles.getLogFileForVersion( logVersion ); LogPositionMarker marker = new LogPositionMarker(); writeSomeData( file, pair -> { LogEntryWriter writer = pair.first(); writer.writeStartEntry( 1, 1, 1L, 1L, ArrayUtils.EMPTY_BYTE_ARRAY ); writer.writeCommitEntry( 1L, 2L ); writer.writeCheckPointEntry( new LogPosition( logVersion, LogHeader.LOG_HEADER_SIZE ) ); writer.writeCheckPointEntry( new LogPosition( logVersion, LogHeader.LOG_HEADER_SIZE ) ); writer.writeCheckPointEntry( new LogPosition( logVersion, LogHeader.LOG_HEADER_SIZE ) ); writer.writeCheckPointEntry( new LogPosition( logVersion, LogHeader.LOG_HEADER_SIZE ) ); Consumer<LogPositionMarker> other = pair.other(); other.accept( marker ); return true; } ); assertTrue( recover( storeDir, logFiles ) ); assertEquals( marker.getByteOffset(), file.length() ); }
@Override public LogPositionMarker getCurrentPosition( LogPositionMarker positionMarker ) throws IOException { positionMarker.unspecified(); return positionMarker; }
@Override public LogPositionMarker getCurrentPosition( LogPositionMarker positionMarker ) throws IOException { positionMarker.mark( logVersionedStoreChannel.getVersion(), channel.position() ); return positionMarker; }
/** * @return last known good position, which is a {@link LogPosition} after a {@link CheckPoint} or * a {@link LogEntryCommit}. */ @Override public LogPosition position() { return lastGoodPositionMarker.newPosition(); } }