public Iterable getContents()

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();
                    }
                };
            }
        };
    }