Search in sources :

Example 1 with ArrayDeque

use of io.dingodb.raft.util.ArrayDeque in project dingo by dingodb.

the class LocalSnapshotCopier method filterBeforeCopy.

boolean filterBeforeCopy(final LocalSnapshotWriter writer, final SnapshotReader lastSnapshot) throws IOException {
    final Set<String> existingFiles = writer.listFiles();
    final ArrayDeque<String> toRemove = new ArrayDeque<>();
    for (final String file : existingFiles) {
        if (this.remoteSnapshot.getFileMeta(file) == null) {
            toRemove.add(file);
            writer.removeFile(file);
        }
    }
    final Set<String> remoteFiles = this.remoteSnapshot.listFiles();
    for (final String fileName : remoteFiles) {
        final LocalFileMeta remoteMeta = (LocalFileMeta) this.remoteSnapshot.getFileMeta(fileName);
        Requires.requireNonNull(remoteMeta, "remoteMeta");
        if (!remoteMeta.hasChecksum()) {
            // Re-download file if this file doesn't have checksum
            writer.removeFile(fileName);
            toRemove.add(fileName);
            continue;
        }
        LocalFileMeta localMeta = (LocalFileMeta) writer.getFileMeta(fileName);
        if (localMeta != null) {
            if (localMeta.hasChecksum() && localMeta.getChecksum().equals(remoteMeta.getChecksum())) {
                LOG.info("Keep file={} checksum={} in {}", fileName, remoteMeta.getChecksum(), writer.getPath());
                continue;
            }
            // Remove files from writer so that the file is to be copied from
            // remote_snapshot or last_snapshot
            writer.removeFile(fileName);
            toRemove.add(fileName);
        }
        // Try find files in last_snapshot
        if (lastSnapshot == null) {
            continue;
        }
        if ((localMeta = (LocalFileMeta) lastSnapshot.getFileMeta(fileName)) == null) {
            continue;
        }
        if (!localMeta.hasChecksum() || !localMeta.getChecksum().equals(remoteMeta.getChecksum())) {
            continue;
        }
        LOG.info("Found the same file ={} checksum={} in lastSnapshot={}", fileName, remoteMeta.getChecksum(), lastSnapshot.getPath());
        if (localMeta.getSource() == FileSource.FILE_SOURCE_LOCAL) {
            final String sourcePath = lastSnapshot.getPath() + File.separator + fileName;
            final String destPath = writer.getPath() + File.separator + fileName;
            FileUtils.deleteQuietly(new File(destPath));
            try {
                Files.createLink(Paths.get(destPath), Paths.get(sourcePath));
            } catch (final IOException e) {
                LOG.error("Fail to link {} to {}", sourcePath, destPath, e);
                continue;
            }
            // Don't delete linked file
            if (!toRemove.isEmpty() && toRemove.peekLast().equals(fileName)) {
                toRemove.pollLast();
            }
        }
        // Copy file from last_snapshot
        writer.addFile(fileName, localMeta);
    }
    if (!writer.sync()) {
        LOG.error("Fail to sync writer on path={}", writer.getPath());
        return false;
    }
    for (final String fileName : toRemove) {
        final String removePath = writer.getPath() + File.separator + fileName;
        FileUtils.deleteQuietly(new File(removePath));
        LOG.info("Deleted file: {}", removePath);
    }
    return true;
}
Also used : IOException(java.io.IOException) LocalFileMeta(io.dingodb.raft.entity.LocalFileMetaOutter.LocalFileMeta) File(java.io.File) ArrayDeque(io.dingodb.raft.util.ArrayDeque)

Aggregations

LocalFileMeta (io.dingodb.raft.entity.LocalFileMetaOutter.LocalFileMeta)1 ArrayDeque (io.dingodb.raft.util.ArrayDeque)1 File (java.io.File)1 IOException (java.io.IOException)1