use of org.neo4j.kernel.impl.transaction.log.PhysicalLogVersionedStoreChannel 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();
}
use of org.neo4j.kernel.impl.transaction.log.PhysicalLogVersionedStoreChannel in project neo4j by neo4j.
the class TransactionLogsRecoveryTest method writeSomeDataWithVersion.
private void writeSomeDataWithVersion(Path file, Visitor<Pair<LogEntryWriter, Consumer<LogPositionMarker>>, IOException> visitor, KernelVersion version) throws IOException {
try (LogVersionedStoreChannel versionedStoreChannel = new PhysicalLogVersionedStoreChannel(fileSystem.write(file), logVersion, CURRENT_LOG_FORMAT_VERSION, file, EMPTY_ACCESSOR);
PositionAwarePhysicalFlushableChecksumChannel writableLogChannel = new PositionAwarePhysicalFlushableChecksumChannel(versionedStoreChannel, new HeapScopedBuffer(1, KibiByte, INSTANCE))) {
writeLogHeader(writableLogChannel, new LogHeader(logVersion, 2L, StoreId.UNKNOWN));
writableLogChannel.beginChecksum();
Consumer<LogPositionMarker> consumer = marker -> {
try {
writableLogChannel.getCurrentPosition(marker);
} catch (IOException e) {
throw new RuntimeException(e);
}
};
LogEntryWriter first = new LogEntryWriter(writableLogChannel, version);
visitor.visit(Pair.of(first, consumer));
}
}
use of org.neo4j.kernel.impl.transaction.log.PhysicalLogVersionedStoreChannel in project neo4j by neo4j.
the class TransactionLogFile method getReader.
private ReadableLogChannel getReader(LogPosition position, LogVersionBridge logVersionBridge, boolean raw) throws IOException {
PhysicalLogVersionedStoreChannel logChannel = openForVersion(position.getLogVersion(), raw);
logChannel.position(position.getByteOffset());
return new ReadAheadLogChannel(logChannel, logVersionBridge, memoryTracker, raw);
}
use of org.neo4j.kernel.impl.transaction.log.PhysicalLogVersionedStoreChannel in project neo4j by neo4j.
the class TransactionLogChannelAllocator method openLogChannel.
public PhysicalLogVersionedStoreChannel openLogChannel(long version, boolean raw) throws IOException {
Path fileToOpen = fileHelper.getLogFileForVersion(version);
if (!fileSystem.fileExists(fileToOpen)) {
throw new NoSuchFileException(fileToOpen.toAbsolutePath().toString());
}
StoreChannel rawChannel = null;
try {
rawChannel = fileSystem.read(fileToOpen);
try (var scopedBuffer = new HeapScopedBuffer(CURRENT_FORMAT_LOG_HEADER_SIZE, logFilesContext.getMemoryTracker())) {
var buffer = scopedBuffer.getBuffer();
LogHeader header = readLogHeader(buffer, rawChannel, true, fileToOpen);
if ((header == null) || (header.getLogVersion() != version)) {
throw new IllegalStateException(format("Unexpected log file header. Expected header version: %d, actual header: %s", version, header != null ? header.toString() : "null header."));
}
var versionedStoreChannel = new PhysicalLogVersionedStoreChannel(rawChannel, version, header.getLogFormatVersion(), fileToOpen, nativeChannelAccessor, raw);
if (!raw) {
nativeChannelAccessor.adviseSequentialAccessAndKeepInCache(rawChannel, version);
}
return versionedStoreChannel;
}
} catch (NoSuchFileException cause) {
throw (NoSuchFileException) new NoSuchFileException(fileToOpen.toAbsolutePath().toString()).initCause(cause);
} catch (Throwable unexpectedError) {
if (rawChannel != null) {
// If we managed to open the file before failing, then close the channel
try {
rawChannel.close();
} catch (IOException e) {
unexpectedError.addSuppressed(e);
}
}
throw unexpectedError;
}
}
use of org.neo4j.kernel.impl.transaction.log.PhysicalLogVersionedStoreChannel in project neo4j by neo4j.
the class ReadAheadLogChannelTest method rawReadAheadChannelOpensRawChannelOnNext.
@Test
void rawReadAheadChannelOpensRawChannelOnNext() throws IOException {
Path path = file(0);
directory.createFile(path.getFileName().toString());
var storeChannel = fileSystem.read(path);
var versionedStoreChannel = new PhysicalLogVersionedStoreChannel(storeChannel, -1, (byte) -1, path, nativeChannelAccessor);
var capturingLogVersionBridge = new RawCapturingLogVersionBridge();
assertThrows(ReadPastEndException.class, () -> {
try (ReadAheadLogChannel channel = new ReadAheadLogChannel(versionedStoreChannel, capturingLogVersionBridge, INSTANCE, true)) {
channel.get();
}
});
assertTrue(capturingLogVersionBridge.isRaw());
}
Aggregations