public static LogPosition start( long logVersion ) { return new LogPosition( logVersion, LOG_HEADER_SIZE ); }
@Override public boolean equals( Object o ) { if ( this == o ) { return true; } if ( o == null || getClass() != o.getClass() ) { return false; } CheckPoint that = (CheckPoint) o; return !(logPosition != null ? !logPosition.equals( that.logPosition ) : that.logPosition != null); }
@Override public void publishAsClosed() { transactionIdStore.transactionClosed( transactionId, logPosition.getLogVersion(), logPosition.getByteOffset() ); }
@Override public boolean next() throws IOException { while ( currentLogTransactionCursor == null || !currentLogTransactionCursor.next() ) { // We've run out of transactions in this log version, back up to a previous one currentVersion--; if ( currentVersion < backToPosition.getLogVersion() ) { return false; } closeCurrent(); LogPosition position = currentVersion > backToPosition.getLogVersion() ? start( currentVersion ) : backToPosition; currentLogTransactionCursor = cursorFactory.apply( position ); } return true; }
private ThrowingFunction<LogPosition,TransactionCursor,IOException> log( int... transactionCounts ) throws IOException { long baseOffset = LogPosition.start( 0 ).getByteOffset(); @SuppressWarnings( "unchecked" ) ThrowingFunction<LogPosition,TransactionCursor,IOException> result = mock( ThrowingFunction.class ); AtomicLong txId = new AtomicLong( 0 ); CommittedTransactionRepresentation[][] logs = new CommittedTransactionRepresentation[transactionCounts.length][]; for ( int logVersion = 0; logVersion < transactionCounts.length; logVersion++ ) { logs[logVersion] = transactions( transactionCounts[logVersion], txId ); } when( result.apply( any( LogPosition.class ) ) ).thenAnswer( invocation -> { LogPosition position = invocation.getArgument( 0 ); if ( position == null ) { // A mockito issue when calling the "when" methods, I believe return null; } // For simplicity the offset means, in this test, the array offset CommittedTransactionRepresentation[] transactions = logs[toIntExact( position.getLogVersion() )]; CommittedTransactionRepresentation[] subset = copyOfRange( transactions, toIntExact( position.getByteOffset() - baseOffset ), transactions.length ); ArrayUtil.reverse( subset ); return given( subset ); } ); return result; }
@Test public void shouldParseCheckPointEntry() throws IOException { // given final CheckPoint checkPoint = new CheckPoint( new LogPosition( 43, 44 ) ); final InMemoryClosableChannel channel = new InMemoryClosableChannel(); channel.putLong( checkPoint.getLogPosition().getLogVersion() ); channel.putLong( checkPoint.getLogPosition().getByteOffset() ); channel.getCurrentPosition( marker ); // when final LogEntryParser parser = version.entryParser( LogEntryByteCodes.CHECK_POINT ); final LogEntry logEntry = parser.parse( version, channel, marker, commandReader ); // then assertEquals( checkPoint, logEntry ); assertFalse( parser.skip() ); }
@Override public RecoveryStartInformation getRecoveryStartInformation() { return new RecoveryStartInformation( LogPosition.start( 0 ), 1 ); }
LogPosition logPosition = new LogPosition( lastClosedTransaction[1], lastClosedTransaction[2] ); String prefix = triggerInfo.describe( lastClosedTransactionId ); logPruning.pruneLogs( logPosition.getLogVersion() ); lastCheckPointedTx = lastClosedTransactionId; return lastClosedTransactionId;
private void removeLastCheckpointRecordFromLastLogFile() throws IOException { LogPosition checkpointPosition = null; LogFile transactionLogFile = logFiles.getLogFile(); VersionAwareLogEntryReader<ReadableLogChannel> entryReader = new VersionAwareLogEntryReader<>(); LogPosition startPosition = LogPosition.start( logFiles.getHighestLogVersion() ); try ( ReadableLogChannel reader = transactionLogFile.getReader( startPosition ) ) { LogEntry logEntry; do { logEntry = entryReader.readLogEntry( reader ); if ( logEntry instanceof CheckPoint ) { checkpointPosition = ((CheckPoint) logEntry).getLogPosition(); } } while ( logEntry != null ); } if ( checkpointPosition != null ) { try ( StoreChannel storeChannel = fileSystemRule.open( logFiles.getHighestLogFile(), OpenMode.READ_WRITE ) ) { storeChannel.truncate( checkpointPosition.getByteOffset() ); } } }
public void setCurrentPosition( LogPosition position ) throws IOException, UnsupportedOperationException { channel.position( position.getByteOffset() ); } }
@Override public int hashCode() { return logPosition != null ? logPosition.hashCode() : 0; }
private PhysicalLogVersionedStoreChannel tryOpenStoreChannel( LogPosition currentPosition ) { try { return logFiles.openForVersion( currentPosition.getLogVersion() ); } catch ( IOException e ) { return null; } }
@Override public void noCommitsAfterLastCheckPoint( LogPosition logPosition ) { log.info( format( "No commits found after last check point (which is at %s)", logPosition != null ? logPosition.toString() : "<no log position given>" ) ); }
@SuppressWarnings( {"EqualsWithItself", "SelfComparison"} ) @Test public void logPositionComparison() { assertEquals( 1, logPositionA.compareTo( logPositionB ) ); assertEquals( -1, logPositionB.compareTo( logPositionA ) ); assertEquals( 0, logPositionA.compareTo( logPositionA ) ); assertEquals( 0, logPositionB.compareTo( logPositionB ) ); } }
while ( currentPosition.getLogVersion() <= maxLogVersion ) storeChannel.position( currentPosition.getByteOffset() ); try ( ReadAheadLogChannel logChannel = new ReadAheadLogChannel( storeChannel ); LogEntryCursor cursor = new LogEntryCursor( logEntryReader, logChannel ) ) monitor.corruptedLogFile( currentPosition.getLogVersion(), t ); return new ExtractedTransactionRecord( true ); currentPosition = LogPosition.start( currentPosition.getLogVersion() + 1 );
@Test public void shouldReadACheckPointLogEntry() throws IOException { // given LogEntryVersion version = LogEntryVersion.CURRENT; final LogPosition logPosition = new LogPosition( 42, 43 ); final CheckPoint checkPoint = new CheckPoint( version, logPosition ); final InMemoryClosableChannel channel = new InMemoryClosableChannel(); channel.put( version.byteCode() ); channel.put( LogEntryByteCodes.CHECK_POINT ); channel.putLong( logPosition.getLogVersion() ); channel.putLong( logPosition.getByteOffset() ); // when final LogEntry logEntry = logEntryReader.readLogEntry( channel ); // then assertEquals( checkPoint, logEntry ); }
long getTimestampForVersion( long version ) throws IOException { LogPosition position = LogPosition.start( version ); try ( ReadableLogChannel channel = logFiles.getLogFile().getReader( position ) ) { LogEntry entry; while ( (entry = logEntryReader.readLogEntry( channel )) != null ) { if ( entry instanceof LogEntryStart ) { return entry.<LogEntryStart>as().getTimeWritten(); } } } return -1; } }
@Override public boolean next() throws IOException { while ( currentLogTransactionCursor == null || !currentLogTransactionCursor.next() ) { // We've run out of transactions in this log version, back up to a previous one currentVersion--; if ( currentVersion < backToPosition.getLogVersion() ) { return false; } closeCurrent(); LogPosition position = currentVersion > backToPosition.getLogVersion() ? start( currentVersion ) : backToPosition; currentLogTransactionCursor = cursorFactory.apply( position ); } return true; }
public TransactionMetadata cacheTransactionMetadata( long txId, LogPosition position, int masterId, int authorId, long checksum, long timeWritten ) { if ( position.getByteOffset() == -1 ) { throw new RuntimeException( "StartEntry.position is " + position ); } TransactionMetadata result = new TransactionMetadata( masterId, authorId, position, checksum, timeWritten ); txStartPositionCache.put( txId, result ); return result; }
@Override public int hashCode() { int result = masterId; result = 31 * result + authorId; result = 31 * result + startPosition.hashCode(); result = 31 * result + (int) (checksum ^ (checksum >>> 32)); result = 31 * result + (int) (timeWritten ^ (timeWritten >>> 32)); return result; } }