Search in sources :

Example 36 with GridNearTxLocal

use of org.apache.ignite.internal.processors.cache.distributed.near.GridNearTxLocal in project ignite by apache.

the class GridCacheAtomicSequenceImpl method internalUpdate.

/**
 * Method returns callable for execution all update operations in async and sync mode.
 *
 * @param l Value will be added to sequence.
 * @param updated If {@code true}, will return updated value, if {@code false}, will return previous value.
 * @return Callable for execution in async and sync mode.
 */
@SuppressWarnings("TooBroadScope")
private Callable<Long> internalUpdate(final long l, final boolean updated) {
    return new Callable<Long>() {

        @Override
        public Long call() throws Exception {
            assert distUpdateFreeTop.isHeldByCurrentThread() || distUpdateLockedTop.isHeldByCurrentThread();
            try (GridNearTxLocal tx = CU.txStartInternal(ctx, cacheView, PESSIMISTIC, REPEATABLE_READ)) {
                GridCacheAtomicSequenceValue seq = cacheView.get(key);
                checkRemoved();
                assert seq != null;
                long curLocVal;
                long newUpBound;
                // Even though we hold a transaction lock here, we must hold the local update lock here as well
                // because we mutate multipe variables (locVal and upBound).
                localUpdate.lock();
                try {
                    curLocVal = locVal;
                    // If local range was already reserved in another thread.
                    if (curLocVal + l <= upBound) {
                        locVal = curLocVal + l;
                        return updated ? curLocVal + l : curLocVal;
                    }
                    long curGlobalVal = seq.get();
                    long newLocVal;
                    /* We should use offset because we already reserved left side of range.*/
                    long off = batchSize > 1 ? batchSize - 1 : 1;
                    // Calculate new values for local counter, global counter and upper bound.
                    if (curLocVal + l >= curGlobalVal) {
                        newLocVal = curLocVal + l;
                        newUpBound = newLocVal + off;
                    } else {
                        newLocVal = curGlobalVal;
                        newUpBound = newLocVal + off;
                    }
                    locVal = newLocVal;
                    upBound = newUpBound;
                    if (updated)
                        curLocVal = newLocVal;
                } finally {
                    localUpdate.unlock();
                }
                // Global counter must be more than reserved upper bound.
                seq.set(newUpBound + 1);
                cacheView.put(key, seq);
                tx.commit();
                return curLocVal;
            } catch (Error | Exception e) {
                U.error(log, "Failed to get and add: " + this, e);
                throw e;
            }
        }
    };
}
Also used : GridNearTxLocal(org.apache.ignite.internal.processors.cache.distributed.near.GridNearTxLocal) Callable(java.util.concurrent.Callable) InvalidObjectException(java.io.InvalidObjectException) IgniteCacheRestartingException(org.apache.ignite.IgniteCacheRestartingException) IgniteCheckedException(org.apache.ignite.IgniteCheckedException) IgniteException(org.apache.ignite.IgniteException) IOException(java.io.IOException) ObjectStreamException(java.io.ObjectStreamException)

Example 37 with GridNearTxLocal

use of org.apache.ignite.internal.processors.cache.distributed.near.GridNearTxLocal in project ignite by apache.

the class IgfsMetaManager method reserveSpace.

/**
 * Reserve space for file.
 *
 * @param fileId File ID.
 * @param space Space.
 * @param affRange Affinity range.
 * @return New file info.
 */
public IgfsEntryInfo reserveSpace(IgniteUuid fileId, long space, IgfsFileAffinityRange affRange) throws IgniteCheckedException {
    validTxState(false);
    if (busyLock.enterBusy()) {
        try {
            if (log.isDebugEnabled())
                log.debug("Reserve file space: " + fileId);
            try (GridNearTxLocal tx = startTx()) {
                // Lock file ID for this transaction.
                IgfsEntryInfo oldInfo = info(fileId);
                if (oldInfo == null)
                    throw fsException("File has been deleted concurrently: " + fileId);
                IgfsEntryInfo newInfo = invokeAndGet(fileId, new IgfsMetaFileReserveSpaceProcessor(space, affRange));
                tx.commit();
                return newInfo;
            } catch (GridClosureException e) {
                throw U.cast(e);
            }
        } finally {
            busyLock.leaveBusy();
        }
    } else
        throw new IllegalStateException("Failed to reserve file space because Grid is stopping:" + fileId);
}
Also used : GridClosureException(org.apache.ignite.internal.util.lang.GridClosureException) IgfsMetaFileReserveSpaceProcessor(org.apache.ignite.internal.processors.igfs.meta.IgfsMetaFileReserveSpaceProcessor) GridNearTxLocal(org.apache.ignite.internal.processors.cache.distributed.near.GridNearTxLocal)

Example 38 with GridNearTxLocal

use of org.apache.ignite.internal.processors.cache.distributed.near.GridNearTxLocal in project ignite by apache.

the class IgfsMetaManager method delete.

/**
 * Remove listing entries of the given parent.
 * This operation actually deletes directories from TRASH, is used solely by IgfsDeleteWorker.
 *
 * @param parentId Parent ID.
 * @param listing Listing entries.
 * @return Collection of really deleted entries.
 * @throws IgniteCheckedException If failed.
 */
Collection<IgniteUuid> delete(IgniteUuid parentId, Map<String, IgfsListingEntry> listing) throws IgniteCheckedException {
    if (busyLock.enterBusy()) {
        try {
            assert parentId != null;
            assert listing != null;
            validTxState(false);
            try (GridNearTxLocal tx = startTx()) {
                Collection<IgniteUuid> res = new HashSet<>();
                // Obtain all necessary locks in one hop.
                IgniteUuid[] allIds = new IgniteUuid[listing.size() + 1];
                allIds[0] = parentId;
                int i = 1;
                for (IgfsListingEntry childEntry : listing.values()) allIds[i++] = childEntry.fileId();
                Map<IgniteUuid, IgfsEntryInfo> locks = lockIds(allIds);
                IgfsEntryInfo parentInfo = locks.get(parentId);
                // Ensure parent is still in place.
                if (parentInfo != null) {
                    Map<String, IgfsListingEntry> parentListing = parentInfo.listing();
                    Map<String, IgfsListingEntry> newListing = new HashMap<>(parentListing.size(), 1.0f);
                    newListing.putAll(parentListing);
                    // Remove child entries if possible.
                    for (Map.Entry<String, IgfsListingEntry> entry : listing.entrySet()) {
                        String childName = entry.getKey();
                        IgniteUuid childId = entry.getValue().fileId();
                        IgfsEntryInfo entryInfo = locks.get(childId);
                        if (entryInfo != null) {
                            // File must be locked for deletion:
                            assert entryInfo.isDirectory() || IgfsUtils.DELETE_LOCK_ID.equals(entryInfo.lockId());
                            // Delete only files or empty folders.
                            if (!entryInfo.hasChildren()) {
                                id2InfoPrj.remove(childId);
                                newListing.remove(childName);
                                res.add(childId);
                            }
                        } else {
                            // Entry was deleted concurrently.
                            newListing.remove(childName);
                            res.add(childId);
                        }
                    }
                    // Update parent listing.
                    id2InfoPrj.put(parentId, parentInfo.listing(newListing));
                }
                tx.commit();
                return res;
            }
        } finally {
            busyLock.leaveBusy();
        }
    } else
        throw new IllegalStateException("Failed to perform delete because Grid is stopping [parentId=" + parentId + ", listing=" + listing + ']');
}
Also used : HashMap(java.util.HashMap) GridNearTxLocal(org.apache.ignite.internal.processors.cache.distributed.near.GridNearTxLocal) IgniteUuid(org.apache.ignite.lang.IgniteUuid) Map(java.util.Map) HashMap(java.util.HashMap) GridLeanMap(org.apache.ignite.internal.util.GridLeanMap) TreeMap(java.util.TreeMap) HashSet(java.util.HashSet)

Example 39 with GridNearTxLocal

use of org.apache.ignite.internal.processors.cache.distributed.near.GridNearTxLocal in project ignite by apache.

the class IgfsMetaManager method move.

/**
 * Move routine.
 *
 * @param srcPath Source path.
 * @param dstPath Destination path.
 * @throws IgniteCheckedException In case of exception.
 */
public void move(IgfsPath srcPath, IgfsPath dstPath) throws IgniteCheckedException {
    if (busyLock.enterBusy()) {
        try {
            validTxState(false);
            // Prepare path IDs.
            IgfsPathIds srcPathIds = pathIds(srcPath);
            IgfsPathIds dstPathIds = pathIds(dstPath);
            // Source path must exists.
            if (!srcPathIds.allExists())
                throw new IgfsPathNotFoundException("Failed to perform move because source path is not " + "found: " + srcPath);
            // At this point we need to understand name of resulting entry. It will be either destination leaf
            // or source leaf depending on existence.
            String dstName;
            if (dstPathIds.lastExists())
                // Full destination path exists -> use source name.
                dstName = srcPathIds.lastPart();
            else {
                if (dstPathIds.lastParentExists()) {
                    // Destination path doesn't exists -> use destination name.
                    dstName = dstPathIds.lastPart();
                    dstPathIds = dstPathIds.parent();
                } else
                    // Destination parent is not found either -> exception.
                    throw new IgfsPathNotFoundException("Failed to perform move because destination path is not " + "found: " + dstPath.parent());
            }
            // Lock participating IDs.
            final Set<IgniteUuid> lockIds = new TreeSet<>(PATH_ID_SORTING_COMPARATOR);
            srcPathIds.addExistingIds(lockIds, relaxed);
            dstPathIds.addExistingIds(lockIds, relaxed);
            try (GridNearTxLocal tx = startTx()) {
                // Obtain the locks.
                final Map<IgniteUuid, IgfsEntryInfo> lockInfos = lockIds(lockIds);
                // Verify integrity of source and destination paths.
                if (!srcPathIds.verifyIntegrity(lockInfos, relaxed))
                    throw new IgfsPathNotFoundException("Failed to perform move because source directory " + "structure changed concurrently [src=" + srcPath + ", dst=" + dstPath + ']');
                if (!dstPathIds.verifyIntegrity(lockInfos, relaxed))
                    throw new IgfsPathNotFoundException("Failed to perform move because destination directory " + "structure changed concurrently [src=" + srcPath + ", dst=" + dstPath + ']');
                // Addiional check: is destination directory?
                IgfsEntryInfo dstParentInfo = lockInfos.get(dstPathIds.lastId());
                if (dstParentInfo.isFile())
                    throw new IgfsPathAlreadyExistsException("Failed to perform move because destination points " + "to existing file [src=" + srcPath + ", dst=" + dstPath + ']');
                // Additional check: does destination already has child with the same name?
                if (dstParentInfo.hasChild(dstName))
                    throw new IgfsPathAlreadyExistsException("Failed to perform move because destination already " + "contains entry with the same name existing file [src=" + srcPath + ", dst=" + dstPath + ']');
                // Actual move: remove from source parent and add to destination target.
                IgfsEntryInfo srcParentInfo = lockInfos.get(srcPathIds.lastParentId());
                IgfsEntryInfo srcInfo = lockInfos.get(srcPathIds.lastId());
                String srcName = srcPathIds.lastPart();
                IgfsListingEntry srcEntry = srcParentInfo.listing().get(srcName);
                transferEntry(srcEntry, srcParentInfo.id(), srcName, dstParentInfo.id(), dstName);
                tx.commit();
                // Fire events.
                IgfsPath newPath = new IgfsPath(dstPathIds.path(), dstName);
                IgfsUtils.sendEvents(igfsCtx.kernalContext(), srcPath, newPath, srcInfo.isFile() ? EVT_IGFS_FILE_RENAMED : EVT_IGFS_DIR_RENAMED);
            }
        } finally {
            busyLock.leaveBusy();
        }
    } else
        throw new IllegalStateException("Failed to perform move because Grid is stopping [srcPath=" + srcPath + ", dstPath=" + dstPath + ']');
}
Also used : GridNearTxLocal(org.apache.ignite.internal.processors.cache.distributed.near.GridNearTxLocal) IgfsPathNotFoundException(org.apache.ignite.igfs.IgfsPathNotFoundException) IgfsPathAlreadyExistsException(org.apache.ignite.igfs.IgfsPathAlreadyExistsException) IgfsPath(org.apache.ignite.igfs.IgfsPath) IgniteUuid(org.apache.ignite.lang.IgniteUuid) TreeSet(java.util.TreeSet)

Example 40 with GridNearTxLocal

use of org.apache.ignite.internal.processors.cache.distributed.near.GridNearTxLocal in project ignite by apache.

the class IgfsMetaManager method delete.

/**
 * Remove entry from the metadata listing.
 * Used solely by IgfsDeleteWorker.
 *
 * @param parentId Parent ID.
 * @param name Name.
 * @param id ID.
 * @return {@code True} in case the entry really was removed from the cache by this call.
 * @throws IgniteCheckedException If failed.
 */
boolean delete(IgniteUuid parentId, String name, IgniteUuid id) throws IgniteCheckedException {
    if (busyLock.enterBusy()) {
        try {
            validTxState(false);
            try (GridNearTxLocal tx = startTx()) {
                Map<IgniteUuid, IgfsEntryInfo> infos = lockIds(parentId, id);
                IgfsEntryInfo victim = infos.get(id);
                if (victim == null)
                    return false;
                assert victim.isDirectory() || IgfsUtils.DELETE_LOCK_ID.equals(victim.lockId()) : " isDir: " + victim.isDirectory() + ", lockId: " + victim.lockId();
                // Proceed only in case both parent and child exist.
                if (infos.containsKey(parentId) && infos.containsKey(id)) {
                    IgfsEntryInfo parentInfo = infos.get(parentId);
                    assert parentInfo != null;
                    IgfsListingEntry childEntry = parentInfo.listing().get(name);
                    if (childEntry != null)
                        id2InfoPrj.invoke(parentId, new IgfsMetaDirectoryListingRemoveProcessor(name, id));
                    id2InfoPrj.remove(id);
                    tx.commit();
                    return true;
                }
                return false;
            }
        } finally {
            busyLock.leaveBusy();
        }
    } else
        throw new IllegalStateException("Failed to perform delete because Grid is stopping [parentId=" + parentId + ", name=" + name + ", id=" + id + ']');
}
Also used : IgniteUuid(org.apache.ignite.lang.IgniteUuid) IgfsMetaDirectoryListingRemoveProcessor(org.apache.ignite.internal.processors.igfs.meta.IgfsMetaDirectoryListingRemoveProcessor) GridNearTxLocal(org.apache.ignite.internal.processors.cache.distributed.near.GridNearTxLocal)

Aggregations

GridNearTxLocal (org.apache.ignite.internal.processors.cache.distributed.near.GridNearTxLocal)51 IgniteCheckedException (org.apache.ignite.IgniteCheckedException)21 IgniteUuid (org.apache.ignite.lang.IgniteUuid)10 IgniteException (org.apache.ignite.IgniteException)9 Map (java.util.Map)8 Nullable (org.jetbrains.annotations.Nullable)8 HashMap (java.util.HashMap)7 GridClosureException (org.apache.ignite.internal.util.lang.GridClosureException)7 TreeSet (java.util.TreeSet)6 UUID (java.util.UUID)6 Callable (java.util.concurrent.Callable)6 ClusterNode (org.apache.ignite.cluster.ClusterNode)5 IgfsException (org.apache.ignite.igfs.IgfsException)5 IgfsPathNotFoundException (org.apache.ignite.igfs.IgfsPathNotFoundException)5 IgniteInternalFuture (org.apache.ignite.internal.IgniteInternalFuture)5 ArrayList (java.util.ArrayList)4 HashSet (java.util.HashSet)4 EVT_NODE_LEFT (org.apache.ignite.events.EventType.EVT_NODE_LEFT)4 IgfsPathAlreadyExistsException (org.apache.ignite.igfs.IgfsPathAlreadyExistsException)4 IgfsPathIsDirectoryException (org.apache.ignite.igfs.IgfsPathIsDirectoryException)4