use of jetbrains.exodus.io.Block in project xodus by JetBrains.
the class Log method closeFullFileFileIfNecessary.
private void closeFullFileFileIfNecessary(BufferedDataWriter writer) {
final boolean shouldCreateNewFile = writer.getLastWrittenFileLength(fileLengthBound) == 0;
if (shouldCreateNewFile) {
// Don't forget to fsync the old file before closing it, otherwise will get a corrupted DB in the case of a
// system failure:
flush(true);
baseWriter.close();
if (config.isFullFileReadonly()) {
final Long lastFile = writer.getFileSetMutable().getMaximum();
if (lastFile != null) {
Block block = reader.getBlock(lastFile);
if (block.length() < fileSize) {
throw new IllegalStateException("file too short");
}
block.setReadOnly();
}
}
} else if (System.currentTimeMillis() > lastSyncTicks + config.getSyncPeriod()) {
flush(true);
}
}
use of jetbrains.exodus.io.Block in project xodus by JetBrains.
the class Log method checkLogConsistency.
private void checkLogConsistency(LogFileSet.Mutable fileSetMutable) {
final Block[] blocks = reader.getBlocks();
for (int i = 0; i < blocks.length; ++i) {
final Block block = blocks[i];
final long address = block.getAddress();
final long blockLength = block.length();
String clearLogReason = null;
// if it is not the last file and its size is not as expected
if (blockLength > fileLengthBound || (i < blocks.length - 1 && blockLength != fileLengthBound)) {
clearLogReason = "Unexpected file length" + LogUtil.getWrongAddressErrorMessage(address, fileSize);
}
// if the file address is not a multiple of fileLengthBound
if (clearLogReason == null && address != getFileAddress(address)) {
if (!config.isClearInvalidLog()) {
throw new ExodusException("Unexpected file address " + LogUtil.getLogFilename(address) + LogUtil.getWrongAddressErrorMessage(address, fileSize));
}
clearLogReason = "Unexpected file address " + LogUtil.getLogFilename(address) + LogUtil.getWrongAddressErrorMessage(address, fileSize);
}
if (clearLogReason != null) {
if (!config.isClearInvalidLog()) {
throw new ExodusException(clearLogReason);
}
logger.error("Clearing log due to: " + clearLogReason);
fileSetMutable.clear();
reader.clear();
break;
}
fileSetMutable.add(address);
}
}
use of jetbrains.exodus.io.Block in project xodus by JetBrains.
the class BufferedDataWriter method writePage.
private void writePage(@NotNull final byte[] bytes, final int off, final int len) {
final Block block = child.write(bytes, off, len);
blockSetMutable.add(block.getAddress(), block);
}
use of jetbrains.exodus.io.Block in project xodus by JetBrains.
the class Log method readBytes.
@SuppressWarnings("ConstantConditions")
int readBytes(final byte[] output, final long address) {
final long fileAddress = getFileAddress(address);
final LogTip logTip = getTip();
final LongIterator files = logTip.logFileSet.getFilesFrom(fileAddress);
if (files.hasNext()) {
final long leftBound = files.nextLong();
final long fileSize = getFileSize(leftBound, logTip);
if (leftBound == fileAddress && fileAddress + fileSize > address) {
final Block block = reader.getBlock(fileAddress);
final int readBytes = block.read(output, address - fileAddress, output.length);
final StreamCipherProvider cipherProvider = config.getCipherProvider();
if (cipherProvider != null) {
EnvKryptKt.cryptBlocksMutable(cipherProvider, config.getCipherKey(), config.getCipherBasicIV(), address, output, 0, readBytes, LogUtil.LOG_BLOCK_ALIGNMENT);
}
notifyReadBytes(output, readBytes);
return readBytes;
}
if (fileAddress < logTip.logFileSet.getMinimum()) {
BlockNotFoundException.raise("Address is out of log space, underflow", this, address);
}
if (fileAddress >= logTip.logFileSet.getMaximum()) {
BlockNotFoundException.raise("Address is out of log space, overflow", this, address);
}
}
BlockNotFoundException.raise(this, address);
return 0;
}
use of jetbrains.exodus.io.Block in project xodus by JetBrains.
the class BufferedDataWriter method getByte.
byte getByte(long address, byte max) {
final int offset = ((int) address) & (pageSize - 1);
final long pageAddress = address - offset;
final MutablePage page = getWrittenPage(pageAddress);
if (page != null) {
final byte result = (byte) (page.bytes[offset] ^ 0x80);
if (result < 0 || result > max) {
throw new IllegalStateException("Unknown written page loggable type: " + result);
}
return result;
}
// slow path: unconfirmed file saved to disk, read byte from it
final long fileAddress = log.getFileAddress(address);
if (!blockSetMutable.contains(fileAddress)) {
BlockNotFoundException.raise("Address is out of log space, underflow", log, address);
}
final byte[] output = new byte[pageSize];
final Block block = blockSetMutable.getBlock(fileAddress);
final int readBytes = block.read(output, pageAddress - fileAddress, 0, output.length);
if (readBytes < offset) {
throw new ExodusException("Can't read expected page bytes");
}
if (cipherProvider != null) {
EnvKryptKt.cryptBlocksMutable(cipherProvider, cipherKey, cipherBasicIV, pageAddress, output, 0, readBytes, LogUtil.LOG_BLOCK_ALIGNMENT);
}
final byte result = (byte) (output[offset] ^ 0x80);
if (result < 0 || result > max) {
throw new IllegalStateException("Unknown written file loggable type: " + result + ", address: " + address);
}
return result;
}
Aggregations