io.datakernel.remotefs.RemoteFsUtils Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of datakernel-fs Show documentation
Show all versions of datakernel-fs Show documentation
Package provides tools for building efficient, scalable remote file servers.
It utilizes CSP for fast and reliable file transfer.
The newest version!
package io.datakernel.remotefs; import io.datakernel.common.exception.UncheckedException; import io.datakernel.promise.Promise; import io.datakernel.promise.Promises; import org.jetbrains.annotations.Nullable; import java.nio.file.FileSystems; import java.nio.file.PathMatcher; import java.nio.file.Paths; import java.util.function.Predicate; import java.util.regex.Pattern; import static io.datakernel.remotefs.FsClient.*; public final class RemoteFsUtils { private static final Pattern ANY_GLOB_METACHARS = Pattern.compile("[*?{}\\[\\]\\\\]"); private static final Pattern UNESCAPED_GLOB_METACHARS = Pattern.compile("(?trueif given glob can match more than one file. */ public static boolean isWildcard(String glob) { return UNESCAPED_GLOB_METACHARS.matcher(glob).find(); } /** * Returns a {@link PathMatcher} for given glob * * @param glob a glob string * @return a path matcher for the glob string */ public static PathMatcher getGlobPathMatcher(String glob) { return FileSystems.getDefault().getPathMatcher("glob:" + glob); } /** * Same as {@link #getGlobPathMatcher(String)} but returns a string predicate. * * @param glob a glob string * @return a predicate for the glob string */ public static PredicategetGlobStringPredicate(String glob) { PathMatcher matcher = getGlobPathMatcher(glob); return str -> matcher.matches(Paths.get(str)); } public static int getErrorCode(Throwable e) { if (e == FILE_NOT_FOUND) { return 1; } if (e == FILE_EXISTS) { return 2; } if (e == BAD_PATH) { return 3; } if (e == OFFSET_TOO_BIG) { return 4; } if (e == LENGTH_TOO_BIG) { return 5; } if (e == BAD_RANGE) { return 6; } if (e == MOVING_DIRS) { return 7; } if (e == UNSUPPORTED_REVISION) { return 8; } return 0; } static void checkRange(long size, long offset, long length) { if (offset < -1 || length < -1) { throw new UncheckedException(BAD_RANGE); } if (offset > size) { throw new UncheckedException(OFFSET_TOO_BIG); } if (length != -1 && offset + length > size) { throw new UncheckedException(LENGTH_TOO_BIG); } } public static Promise copyFile(FsClient source, FsClient target, String name) { return copyFile(source, target, name, null); } public static Promise copyFile(FsClient from, FsClient to, String name, @Nullable Long newRevision) { return Promises.toTuple(from.getMetadata(name), to.getMetadata(name)) .then(t -> { FileMetadata sourceMeta = t.getValue1(); FileMetadata targetMeta = t.getValue2(); if (sourceMeta == null) { // no such original file, do nothing return Promise.complete(); } long sourceRevision = newRevision != null ? newRevision : sourceMeta.getRevision(); if (sourceMeta.isTombstone()) { if (targetMeta != null && sourceRevision < targetMeta.getRevision()) { // target meta is better than our tombstone, do nothing return Promise.complete(); } // else create the same tombstone on target return to.delete(name, sourceRevision); } if (targetMeta == null || sourceRevision > targetMeta.getRevision()) { // simply copy over when target has no such file or when source file is better return from.download(name) .then(supplier -> supplier.streamTo(to.upload(name, 0, sourceRevision))); } if (sourceRevision < targetMeta.getRevision()) { // do nothing when target file is better return Promise.complete(); } // * the revisions are equal here if (sourceMeta.getSize() <= targetMeta.getSize()) { // if target is the same or bigger then it is better, do nothing return Promise.complete(); } // else we copy over only the part that is missing on target return from.download(name, sourceMeta.getSize()) .then(supplier -> supplier.streamTo(to.upload(name, sourceMeta.getSize(), sourceRevision))); }); } }
© 2015 - 2025 Weber Informatics LLC | Privacy Policy