in environment/src/main/java/jetbrains/exodus/env/EnvironmentBackupStrategyImpl.java [68:222]
public Iterable<VirtualFileDescriptor> getContents() {
environment.flushAndSync();
return new Iterable<>() {
private final File[] files = IOUtil.listFiles(new File(environment.getLocation()));
private int i = 0;
private VirtualFileDescriptor next;
@NotNull
@Override
public Iterator<VirtualFileDescriptor> iterator() {
return new Iterator<>() {
@Override
public boolean hasNext() {
if (next != null) {
return true;
}
while (i < files.length) {
final File file = files[i++];
if (file.isFile()) {
final long fileSize = file.length();
final String logFileName = file.getName();
if (fileSize != 0 && logFileName.endsWith(LogUtil.LOG_FILE_EXTENSION)) {
final long fileAddress = LogUtil.getAddress(file.getName());
if (fileLastAddress < fileAddress) {
break;
}
if (fileLastAddress > fileAddress && fileSize < fileLengthBound) {
DataCorruptionException.raise("Size of the file is less than expected. {expected : " +
fileLengthBound + ", actual : " + fileSize + " }",
environment.getLog(), fileAddress);
}
final long updatedFileSize = Math.min(fileSize, highAddress - fileAddress);
next = new FileDescriptor(file, "", updatedFileSize) {
@Override
public @NotNull InputStream getInputStream() throws IOException {
return new FileDescriptorInputStream(new FileInputStream(file),
fileAddress, pageSize, getFileSize(),
highAddress - fileAddress,
environment.getLog(), environment.getCipherProvider(),
environment.getCipherKey(), environment.getCipherBasicIV());
}
};
return true;
}
}
}
if (!backupMetadataWasSent) {
backupMetadataWasSent = true;
final ByteBuffer backupMetadataContent =
BackupMetadata.serialize(0, environment.getCurrentFormatVersion(), rootAddress,
environment.getLog().getCachePageSize(),
environment.getLog().getFileLengthBound(),
true, fileLastAddress, lastFileOffset);
next = new FileDescriptor(new File(BackupMetadata.BACKUP_METADATA_FILE_NAME),
"", backupMetadataContent.remaining()) {
@Override
public @NotNull InputStream getInputStream() {
return new ByteArrayInputStream(backupMetadataContent.array(),
backupMetadataContent.arrayOffset(), backupMetadataContent.remaining());
}
@Override
public boolean shouldCloseStream() {
return false;
}
@Override
public boolean hasContent() {
return true;
}
@Override
public long getTimeStamp() {
return System.currentTimeMillis();
}
@Override
public boolean canBeEncrypted() {
return false;
}
};
return true;
} else if (!startupMetadataWasSent) {
startupMetadataWasSent = true;
final ByteBuffer startupMetadataContent =
StartupMetadata.serialize(0, environment.getCurrentFormatVersion(), rootAddress,
environment.getLog().getCachePageSize(),
environment.getLog().getFileLengthBound(),
false);
next = new FileDescriptor(new File(StartupMetadata.ZERO_FILE_NAME),
"", startupMetadataContent.remaining()) {
@Override
public @NotNull InputStream getInputStream() {
return new ByteArrayInputStream(startupMetadataContent.array(),
startupMetadataContent.arrayOffset(), startupMetadataContent.remaining());
}
@Override
public boolean shouldCloseStream() {
return false;
}
@Override
public boolean hasContent() {
return true;
}
@Override
public long getTimeStamp() {
return System.currentTimeMillis();
}
@Override
public boolean canBeEncrypted() {
return false;
}
};
return true;
}
return false;
}
@Override
public VirtualFileDescriptor next() {
if (!hasNext()) {
throw new NoSuchElementException();
}
final VirtualFileDescriptor result = next;
next = null;
return result;
}
@Override
public void remove() {
throw new UnsupportedOperationException();
}
};
}
};
}