use of org.neo4j.kernel.impl.transaction.log.ReaderLogVersionBridge in project neo4j by neo4j.
the class DumpLogicalLog method dump.
public void dump(String filenameOrDirectory, PrintStream out, Predicate<LogEntry[]> filter, Function<LogEntry, String> serializer) throws IOException {
File file = new File(filenameOrDirectory);
printFile(file, out);
File firstFile;
LogVersionBridge bridge;
if (file.isDirectory()) {
// Use natural log version bridging if a directory is supplied
final PhysicalLogFiles logFiles = new PhysicalLogFiles(file, fileSystem);
bridge = new ReaderLogVersionBridge(fileSystem, logFiles) {
@Override
public LogVersionedStoreChannel next(LogVersionedStoreChannel channel) throws IOException {
LogVersionedStoreChannel next = super.next(channel);
if (next != channel) {
printFile(logFiles.getLogFileForVersion(next.getVersion()), out);
}
return next;
}
};
firstFile = logFiles.getLogFileForVersion(logFiles.getLowestLogVersion());
} else {
// Use no bridging, simple reading this single log file if a file is supplied
firstFile = file;
bridge = NO_MORE_CHANNELS;
}
StoreChannel fileChannel = fileSystem.open(firstFile, "r");
ByteBuffer buffer = ByteBuffer.allocateDirect(LOG_HEADER_SIZE);
LogHeader logHeader;
try {
logHeader = readLogHeader(buffer, fileChannel, false, firstFile);
} catch (IOException ex) {
out.println("Unable to read timestamp information, no records in logical log.");
out.println(ex.getMessage());
fileChannel.close();
throw ex;
}
out.println("Logical log format: " + logHeader.logFormatVersion + " version: " + logHeader.logVersion + " with prev committed tx[" + logHeader.lastCommittedTxId + "]");
PhysicalLogVersionedStoreChannel channel = new PhysicalLogVersionedStoreChannel(fileChannel, logHeader.logVersion, logHeader.logFormatVersion);
ReadableClosablePositionAwareChannel logChannel = new ReadAheadLogChannel(channel, bridge, DEFAULT_READ_AHEAD_SIZE);
LogEntryReader<ReadableClosablePositionAwareChannel> entryReader = new VersionAwareLogEntryReader<>();
IOCursor<LogEntry> entryCursor = new LogEntryCursor(entryReader, logChannel);
TransactionLogEntryCursor transactionCursor = new TransactionLogEntryCursor(entryCursor);
try (IOCursor<LogEntry[]> cursor = filter == null ? transactionCursor : new FilteringIOCursor<>(transactionCursor, filter)) {
while (cursor.next()) {
for (LogEntry entry : cursor.get()) {
out.println(serializer.apply(entry));
}
}
}
}
use of org.neo4j.kernel.impl.transaction.log.ReaderLogVersionBridge in project neo4j by neo4j.
the class ReaderLogVersionBridgeTest method shouldReturnOldChannelWhenThereIsNoNextChannel.
@Test
void shouldReturnOldChannelWhenThereIsNoNextChannel() throws IOException {
// given
final ReaderLogVersionBridge bridge = new ReaderLogVersionBridge(logFiles.getLogFile());
when(channel.getVersion()).thenReturn(version);
when(fs.read(any(Path.class))).thenThrow(new NoSuchFileException("mock"));
// when
final LogVersionedStoreChannel result = bridge.next(channel, false);
// then
assertEquals(channel, result);
verify(channel, never()).close();
}
use of org.neo4j.kernel.impl.transaction.log.ReaderLogVersionBridge in project neo4j by neo4j.
the class ReaderLogVersionBridgeTest method shouldReturnOldChannelWhenNextChannelHasNotGottenCompleteHeaderYet.
@Test
void shouldReturnOldChannelWhenNextChannelHasNotGottenCompleteHeaderYet() throws Exception {
// given
final ReaderLogVersionBridge bridge = new ReaderLogVersionBridge(logFiles.getLogFile());
final StoreChannel nextVersionWithIncompleteHeader = mock(StoreChannel.class);
when(nextVersionWithIncompleteHeader.read(any(ByteBuffer.class))).thenReturn(CURRENT_FORMAT_LOG_HEADER_SIZE / 2);
when(channel.getVersion()).thenReturn(version);
when(fs.fileExists(any(Path.class))).thenReturn(true);
when(fs.read(any(Path.class))).thenReturn(nextVersionWithIncompleteHeader);
// when
final LogVersionedStoreChannel result = bridge.next(channel, false);
// then
assertEquals(channel, result);
verify(channel, never()).close();
}
use of org.neo4j.kernel.impl.transaction.log.ReaderLogVersionBridge in project neo4j by neo4j.
the class ReaderLogVersionBridgeTest method shouldReturnOldChannelWhenNextChannelHasntGottenCompleteHeaderYet.
@Test
public void shouldReturnOldChannelWhenNextChannelHasntGottenCompleteHeaderYet() throws Exception {
// given
final ReaderLogVersionBridge bridge = new ReaderLogVersionBridge(fs, logFiles);
final StoreChannel nextVersionWithIncompleteHeader = mock(StoreChannel.class);
when(nextVersionWithIncompleteHeader.read(any(ByteBuffer.class))).thenReturn(LOG_HEADER_SIZE / 2);
when(channel.getVersion()).thenReturn(version);
when(fs.fileExists(file)).thenReturn(true);
when(logFiles.getLogFileForVersion(version + 1)).thenReturn(file);
when(fs.open(file, "r")).thenReturn(nextVersionWithIncompleteHeader);
// when
final LogVersionedStoreChannel result = bridge.next(channel);
// then
assertEquals(channel, result);
verify(channel, never()).close();
}
use of org.neo4j.kernel.impl.transaction.log.ReaderLogVersionBridge in project neo4j by neo4j.
the class ReaderLogVersionBridgeTest method shouldOpenTheNextChannelWhenItExists.
@Test
void shouldOpenTheNextChannelWhenItExists() throws IOException {
// given
final StoreChannel newStoreChannel = mock(StoreChannel.class);
final ReaderLogVersionBridge bridge = new ReaderLogVersionBridge(logFiles.getLogFile());
when(channel.getVersion()).thenReturn(version);
when(channel.getLogFormatVersion()).thenReturn(CURRENT_LOG_FORMAT_VERSION);
when(fs.fileExists(any(Path.class))).thenReturn(true);
when(fs.read(any(Path.class))).thenReturn(newStoreChannel);
when(newStoreChannel.read(ArgumentMatchers.<ByteBuffer>any())).then(new Answer<>() {
private int count;
@Override
public Integer answer(InvocationOnMock invocation) {
count++;
ByteBuffer buffer = invocation.getArgument(0);
if (count == 1) {
buffer.putLong(encodeLogVersion(version + 1, CURRENT_LOG_FORMAT_VERSION));
return Long.BYTES;
}
if (count == 2) {
buffer.putLong(42);
buffer.putLong(1);
buffer.putLong(2);
buffer.putLong(3);
buffer.putLong(4);
buffer.putLong(5);
// reserved
buffer.putLong(0);
return Long.BYTES * 7;
}
throw new AssertionError("Should only be called twice.");
}
});
// when
final LogVersionedStoreChannel result = bridge.next(channel, false);
// then
PhysicalLogVersionedStoreChannel expected = new PhysicalLogVersionedStoreChannel(newStoreChannel, version + 1, CURRENT_LOG_FORMAT_VERSION, Path.of("log.file"), ChannelNativeAccessor.EMPTY_ACCESSOR);
assertEquals(expected, result);
verify(channel).close();
}
Aggregations