Search in sources :

Example 81 with IgfsPath

use of org.apache.ignite.igfs.IgfsPath in project ignite by apache.

the class IgfsUtils method preparePathModes.

/**
 * Checks, filters and sorts the modes.
 *
 * @param dfltMode The root mode. Must always be not null.
 * @param modes The subdirectory modes.
 * @param dualParentsContainingPrimaryChildren The set to store parents into.
 * @return Descending list of filtered and checked modes.
 * @throws IgniteCheckedException On error.
 */
public static ArrayList<T2<IgfsPath, IgfsMode>> preparePathModes(final IgfsMode dfltMode, @Nullable List<T2<IgfsPath, IgfsMode>> modes, Set<IgfsPath> dualParentsContainingPrimaryChildren) throws IgniteCheckedException {
    if (modes == null)
        return null;
    // Sort by depth, shallow first.
    Collections.sort(modes, new Comparator<Map.Entry<IgfsPath, IgfsMode>>() {

        @Override
        public int compare(Map.Entry<IgfsPath, IgfsMode> o1, Map.Entry<IgfsPath, IgfsMode> o2) {
            return o1.getKey().depth() - o2.getKey().depth();
        }
    });
    ArrayList<T2<IgfsPath, IgfsMode>> resModes = new ArrayList<>(modes.size() + 1);
    resModes.add(new T2<>(IgfsPath.ROOT, dfltMode));
    for (T2<IgfsPath, IgfsMode> mode : modes) {
        assert mode.getKey() != null;
        for (T2<IgfsPath, IgfsMode> resMode : resModes) {
            if (mode.getKey().isSubDirectoryOf(resMode.getKey())) {
                assert resMode.getValue() != null;
                if (resMode.getValue() == mode.getValue())
                    // No reason to add a sub-path of the same mode, ignore this pair.
                    break;
                if (!canContain(resMode.getValue(), mode.getValue()))
                    throw new IgniteCheckedException("Subdirectory " + mode.getKey() + " mode " + mode.getValue() + " is not compatible with upper level " + resMode.getKey() + " directory mode " + resMode.getValue() + ".");
                // Add to the 1st position (deep first).
                resModes.add(0, mode);
                // Store primary paths inside dual paths in separate collection:
                if (mode.getValue() == PRIMARY)
                    dualParentsContainingPrimaryChildren.add(mode.getKey().parent());
                break;
            }
        }
    }
    // Remove root, because this class contract is that root mode is not contained in the list.
    resModes.remove(resModes.size() - 1);
    return resModes;
}
Also used : ArrayList(java.util.ArrayList) IgfsPath(org.apache.ignite.igfs.IgfsPath) IgfsMode(org.apache.ignite.igfs.IgfsMode) IgniteCheckedException(org.apache.ignite.IgniteCheckedException) Map(java.util.Map) HashMap(java.util.HashMap) T2(org.apache.ignite.internal.util.typedef.T2)

Example 82 with IgfsPath

use of org.apache.ignite.igfs.IgfsPath in project ignite by apache.

the class IgfsUtils method readPath.

/**
 * Read IGFS path.
 *
 * @param reader Reader.
 * @return Path.
 */
@Nullable
public static IgfsPath readPath(BinaryRawReader reader) {
    if (reader.readBoolean()) {
        IgfsPath path = new IgfsPath();
        path.readRawBinary(reader);
        return path;
    } else
        return null;
}
Also used : IgfsPath(org.apache.ignite.igfs.IgfsPath) Nullable(org.jetbrains.annotations.Nullable)

Example 83 with IgfsPath

use of org.apache.ignite.igfs.IgfsPath in project ignite by apache.

the class IgfsDeleteWorker method delete.

/**
 * Remove particular entry from the TRASH directory.
 *
 * @param trashId ID of the trash directory.
 * @param name Entry name.
 * @param id Entry ID.
 * @return {@code True} in case the entry really was deleted form the file system by this call.
 * @throws IgniteCheckedException If failed.
 */
private boolean delete(IgniteUuid trashId, String name, IgniteUuid id) throws IgniteCheckedException {
    assert name != null;
    assert id != null;
    while (true) {
        IgfsEntryInfo info = meta.info(id);
        if (info != null) {
            if (info.isDirectory()) {
                if (!deleteDirectoryContents(trashId, id))
                    return false;
                if (meta.delete(trashId, name, id))
                    return true;
            } else {
                assert info.isFile();
                // Lock the file with special lock Id to prevent concurrent writing:
                IgfsEntryInfo lockedInfo = meta.lock(id, true);
                if (lockedInfo == null)
                    // File is locked, we cannot delete it.
                    return false;
                assert id.equals(lockedInfo.id());
                // Delete file content first.
                // In case this node crashes, other node will re-delete the file.
                data.delete(lockedInfo).get();
                boolean ret = meta.delete(trashId, name, id);
                if (ret) {
                    IgfsPath path = IgfsUtils.extractOriginalPathFromTrash(name);
                    assert path != null;
                    IgfsUtils.sendEvents(igfsCtx.kernalContext(), path, EVT_IGFS_FILE_PURGED);
                }
                return ret;
            }
        } else
            // Entry was deleted concurrently.
            return false;
    }
}
Also used : IgfsPath(org.apache.ignite.igfs.IgfsPath)

Example 84 with IgfsPath

use of org.apache.ignite.igfs.IgfsPath in project ignite by apache.

the class IgfsMetaManager method synchronizeAndExecute.

/**
 * Synchronize file system structure and then execute provided task. All these actions are performed withing
 * the transaction.
 *
 * @param task Task to execute.
 * @param fs File system.
 * @param strict Whether paths must be re-created strictly.
 * @param extraLockIds Additional IDs to lock (optional).
 * @param paths Paths to synchronize.
 * @return Result of task execution.
 * @throws IgniteCheckedException If failed.
 */
@SuppressWarnings({ "Contract", "ConstantConditions" })
private <T> T synchronizeAndExecute(SynchronizationTask<T> task, IgfsSecondaryFileSystem fs, boolean strict, @Nullable Collection<IgniteUuid> extraLockIds, IgfsPath... paths) throws IgniteCheckedException {
    assert task != null;
    assert fs != null;
    assert paths != null && paths.length > 0;
    // Sort paths so that we know in which order to synchronize them.
    if (paths.length > 1)
        Arrays.sort(paths);
    boolean finished = false;
    T res = null;
    while (!finished) {
        // Obtain existing IDs outside the transaction.
        List<List<IgniteUuid>> pathIds = new ArrayList<>(paths.length);
        for (IgfsPath path : paths) pathIds.add(idsForPath(path));
        // Start pessimistic.
        try (GridNearTxLocal tx = startTx()) {
            // Lock the very first existing parents and possibly the leaf as well.
            Map<IgfsPath, IgfsPath> pathToParent = new HashMap<>();
            Map<IgfsPath, IgniteUuid> pathToId = new HashMap<>();
            for (int i = 0; i < paths.length; i++) {
                IgfsPath path = paths[i];
                // Determine the very first existing parent
                List<IgniteUuid> ids = pathIds.get(i);
                if (ids.size() > 1) {
                    // The path is not root.
                    IgfsPath parentPath = path.parent();
                    IgniteUuid parentId = ids.get(ids.size() - 2);
                    for (int j = ids.size() - 3; j >= 0; j--) {
                        if (parentId != null)
                            break;
                        else {
                            parentPath = parentPath.parent();
                            parentId = ids.get(j);
                        }
                    }
                    assert parentPath != null && parentId != null;
                    pathToParent.put(path, parentPath);
                    pathToId.put(parentPath, parentId);
                }
                IgniteUuid pathId = ids.get(ids.size() - 1);
                if (pathId != null)
                    pathToId.put(path, pathId);
            }
            IgniteUuid[] lockArr = new IgniteUuid[extraLockIds == null ? pathToId.size() : pathToId.size() + extraLockIds.size()];
            int idx = 0;
            for (IgniteUuid id : pathToId.values()) lockArr[idx++] = id;
            if (extraLockIds != null) {
                for (IgniteUuid id : extraLockIds) lockArr[idx++] = id;
            }
            Map<IgniteUuid, IgfsEntryInfo> idToInfo = lockIds(lockArr);
            if (extraLockIds != null) {
                for (IgniteUuid id : extraLockIds) idToInfo.remove(id);
            }
            // Ensure that locked IDs still point to expected paths.
            IgfsPath changed = null;
            for (Map.Entry<IgfsPath, IgniteUuid> entry : pathToId.entrySet()) {
                if (!idToInfo.containsKey(entry.getValue()) || !F.eq(entry.getValue(), fileId(entry.getKey(), true))) {
                    changed = entry.getKey();
                    break;
                }
            }
            if (changed != null) {
                finished = true;
                throw fsException(new IgfsConcurrentModificationException("File system entry has been " + "modified concurrently: " + changed));
            } else {
                boolean newParents = false;
                // Check whether any new parents appeared before we have obtained the locks.
                for (int i = 0; i < paths.length; i++) {
                    List<IgniteUuid> newIds = fileIds(paths[i], true);
                    if (!pathIds.get(i).equals(newIds)) {
                        newParents = true;
                        break;
                    }
                }
                if (newParents)
                    // Release all locks and try again.
                    continue;
                else {
                    // Perform synchronization.
                    Map<IgfsPath, IgfsEntryInfo> infos = new HashMap<>();
                    TreeMap<IgfsPath, IgfsEntryInfo> created = new TreeMap<>();
                    for (IgfsPath path : paths) {
                        IgfsPath parentPath = path.parent();
                        if (pathToId.containsKey(path)) {
                            infos.put(path, info(pathToId.get(path)));
                            if (parentPath != null)
                                infos.put(parentPath, info(pathToId.get(parentPath)));
                        } else {
                            IgfsPath firstParentPath = pathToParent.get(path);
                            assert firstParentPath != null;
                            assert pathToId.get(firstParentPath) != null;
                            IgfsEntryInfo info = synchronize(fs, firstParentPath, idToInfo.get(pathToId.get(firstParentPath)), path, strict, created);
                            assert strict && info != null || !strict;
                            if (info != null)
                                infos.put(path, info);
                            if (parentPath != null) {
                                if (parentPath.equals(firstParentPath))
                                    infos.put(firstParentPath, idToInfo.get(pathToId.get(firstParentPath)));
                                else {
                                    assert strict && created.get(parentPath) != null || !strict;
                                    if (created.get(parentPath) != null)
                                        infos.put(parentPath, created.get(parentPath));
                                    else {
                                        // Put the last created path.
                                        infos.put(created.lastKey(), created.get(created.lastKey()));
                                    }
                                }
                            }
                        }
                    }
                    // Finally, execute the task.
                    finished = true;
                    try {
                        res = task.onSuccess(infos);
                    } catch (Exception e) {
                        res = task.onFailure(e);
                    }
                }
            }
            tx.commit();
        } catch (IgniteCheckedException e) {
            if (!finished) {
                finished = true;
                res = task.onFailure(e);
            } else
                throw e;
        }
    }
    return res;
}
Also used : HashMap(java.util.HashMap) IgfsConcurrentModificationException(org.apache.ignite.igfs.IgfsConcurrentModificationException) ArrayList(java.util.ArrayList) GridNearTxLocal(org.apache.ignite.internal.processors.cache.distributed.near.GridNearTxLocal) TreeMap(java.util.TreeMap) IgfsPathAlreadyExistsException(org.apache.ignite.igfs.IgfsPathAlreadyExistsException) IgfsParentNotDirectoryException(org.apache.ignite.igfs.IgfsParentNotDirectoryException) IgfsPathIsDirectoryException(org.apache.ignite.igfs.IgfsPathIsDirectoryException) IgniteCheckedException(org.apache.ignite.IgniteCheckedException) IgniteException(org.apache.ignite.IgniteException) ClusterTopologyException(org.apache.ignite.cluster.ClusterTopologyException) IgniteInterruptedException(org.apache.ignite.IgniteInterruptedException) IgniteInterruptedCheckedException(org.apache.ignite.internal.IgniteInterruptedCheckedException) IgfsDirectoryNotEmptyException(org.apache.ignite.igfs.IgfsDirectoryNotEmptyException) IgfsException(org.apache.ignite.igfs.IgfsException) IgfsConcurrentModificationException(org.apache.ignite.igfs.IgfsConcurrentModificationException) IgfsPathIsNotDirectoryException(org.apache.ignite.igfs.IgfsPathIsNotDirectoryException) IgfsPathNotFoundException(org.apache.ignite.igfs.IgfsPathNotFoundException) GridClosureException(org.apache.ignite.internal.util.lang.GridClosureException) IgfsPath(org.apache.ignite.igfs.IgfsPath) IgniteCheckedException(org.apache.ignite.IgniteCheckedException) IgniteUuid(org.apache.ignite.lang.IgniteUuid) List(java.util.List) ArrayList(java.util.ArrayList) LinkedList(java.util.LinkedList) Map(java.util.Map) HashMap(java.util.HashMap) GridLeanMap(org.apache.ignite.internal.util.GridLeanMap) TreeMap(java.util.TreeMap)

Example 85 with IgfsPath

use of org.apache.ignite.igfs.IgfsPath in project ignite by apache.

the class IgfsMetaManager method synchronize.

/**
 * Synchronize directory structure with the secondary file system.
 *
 * @param fs Secondary file system.
 * @param startPath Start path.
 * @param startPathInfo Start path info.
 * @param endPath End path.
 * @param strict Whether all paths must exist in the secondary file system.
 * @param created Optional map where data about all created values is put.
 * @return File info of the end path.
 * @throws IgniteCheckedException If failed.
 */
private IgfsEntryInfo synchronize(IgfsSecondaryFileSystem fs, IgfsPath startPath, IgfsEntryInfo startPathInfo, IgfsPath endPath, boolean strict, @Nullable Map<IgfsPath, IgfsEntryInfo> created) throws IgniteCheckedException {
    assert fs != null;
    assert startPath != null && startPathInfo != null && endPath != null;
    validTxState(true);
    IgfsEntryInfo parentInfo = startPathInfo;
    List<String> components = endPath.components();
    IgfsPath curPath = startPath;
    for (int i = startPath.components().size(); i < components.size(); i++) {
        curPath = new IgfsPath(curPath, components.get(i));
        if (created != null && created.containsKey(curPath))
            // Re-use already created info.
            parentInfo = created.get(curPath);
        else {
            // Get file status from the secondary file system.
            IgfsFile status;
            try {
                status = fs.info(curPath);
            } catch (IgniteException e) {
                throw new IgniteCheckedException("Failed to get path information: " + e, e);
            }
            if (status != null) {
                if (!status.isDirectory() && !curPath.equals(endPath))
                    throw new IgniteCheckedException("Failed to create path the locally because secondary file " + "system directory structure was modified concurrently and the path is not a directory as " + "expected: " + curPath);
            } else {
                if (strict) {
                    throw new IgniteCheckedException("Failed to create path locally due to secondary file system " + "exception: " + curPath);
                } else if (created != null)
                    created.put(curPath.parent(), parentInfo);
                return null;
            }
            // Recreate the path locally.
            IgfsEntryInfo curInfo = status.isDirectory() ? IgfsUtils.createDirectory(IgniteUuid.randomUuid(), null, status.properties(), status.accessTime(), status.modificationTime()) : IgfsUtils.createFile(IgniteUuid.randomUuid(), igfsCtx.configuration().getBlockSize(), status.length(), null, null, igfsCtx.igfs().evictExclude(curPath, false), status.properties(), status.accessTime(), status.modificationTime());
            assert parentInfo != null;
            IgniteUuid oldId = putIfAbsentNonTx(parentInfo.id(), components.get(i), curInfo);
            if (oldId != null)
                curInfo = info(oldId);
            if (created != null)
                created.put(curPath, curInfo);
            parentInfo = curInfo;
        }
    }
    return parentInfo;
}
Also used : IgfsPath(org.apache.ignite.igfs.IgfsPath) IgniteCheckedException(org.apache.ignite.IgniteCheckedException) IgniteException(org.apache.ignite.IgniteException) IgniteUuid(org.apache.ignite.lang.IgniteUuid) IgfsFile(org.apache.ignite.igfs.IgfsFile)

Aggregations

IgfsPath (org.apache.ignite.igfs.IgfsPath)161 IgfsOutputStream (org.apache.ignite.igfs.IgfsOutputStream)24 IOException (java.io.IOException)22 ArrayList (java.util.ArrayList)15 IgniteCheckedException (org.apache.ignite.IgniteCheckedException)14 HashMap (java.util.HashMap)13 IgniteException (org.apache.ignite.IgniteException)13 IgniteFileSystem (org.apache.ignite.IgniteFileSystem)13 IgfsFile (org.apache.ignite.igfs.IgfsFile)13 IgfsException (org.apache.ignite.igfs.IgfsException)12 IgniteUuid (org.apache.ignite.lang.IgniteUuid)11 IgfsBlockLocation (org.apache.ignite.igfs.IgfsBlockLocation)10 Map (java.util.Map)9 Path (org.apache.hadoop.fs.Path)9 IgfsInputStream (org.apache.ignite.igfs.IgfsInputStream)9 IgfsPathNotFoundException (org.apache.ignite.igfs.IgfsPathNotFoundException)8 FileNotFoundException (java.io.FileNotFoundException)6 OutputStream (java.io.OutputStream)6 IgfsDirectoryNotEmptyException (org.apache.ignite.igfs.IgfsDirectoryNotEmptyException)6 IgfsParentNotDirectoryException (org.apache.ignite.igfs.IgfsParentNotDirectoryException)6