/** * Creates a future that will wait for all explicit locks acquired on given topology version to be * released. * * @param topVer Topology version to wait for. * @return Explicit locks release future. */ public IgniteInternalFuture<?> finishExplicitLocks(AffinityTopologyVersion topVer) { GridCompoundFuture<Object, Object> res = new GridCompoundFuture<>(); for (GridCacheExplicitLockSpan span : pendingExplicit.values()) { AffinityTopologyVersion snapshot = span.topologyVersion(); if (snapshot != null && snapshot.compareTo(topVer) < 0) res.add(span.releaseFuture()); } res.markInitialized(); return res; }
/** * Creates multi update finish future. Will return {@code null} if no multi-update locks are * found. * * @param topVer Topology version. * @return Finish future. */ @Nullable public IgniteInternalFuture<?> multiUpdateFinishFuture(AffinityTopologyVersion topVer) { GridCompoundFuture<IgniteUuid, Object> fut = null; for (MultiUpdateFuture multiFut : multiTxFuts.values()) { if (multiFut.topologyVersion().compareTo(topVer) <= 0) { if (fut == null) fut = new GridCompoundFuture<>(); fut.add(multiFut); } } if (fut != null) fut.markInitialized(); return fut; }
/** * @param topVer Topology version to finish. * @return Finish update future. */ @SuppressWarnings("unchecked") public IgniteInternalFuture<?> finishAtomicUpdates(AffinityTopologyVersion topVer) { GridCompoundFuture<Object, Object> res = new GridCompoundFuture<>(); res.ignoreChildFailures( ClusterTopologyCheckedException.class, CachePartialUpdateCheckedException.class); for (GridCacheAtomicFuture<?> fut : atomicFuts.values()) { IgniteInternalFuture<Void> complete = fut.completeFuture(topVer); if (complete != null) res.add((IgniteInternalFuture) complete); } res.markInitialized(); return res; }
/** * Remove particular entry from the trash directory or subdirectory. * * @param parentId Parent ID. * @param id Entry id. * @throws IgniteCheckedException If delete failed for some reason. */ private void deleteDirectory(IgniteUuid parentId, IgniteUuid id) throws IgniteCheckedException { assert parentId != null; assert id != null; while (true) { IgfsFileInfo info = meta.info(id); if (info != null) { assert info.isDirectory(); Map<String, IgfsListingEntry> listing = info.listing(); if (listing.isEmpty()) return; // Directory is empty. Map<String, IgfsListingEntry> delListing; if (listing.size() <= MAX_DELETE_BATCH) delListing = listing; else { delListing = new HashMap<>(MAX_DELETE_BATCH, 1.0f); int i = 0; for (Map.Entry<String, IgfsListingEntry> entry : listing.entrySet()) { delListing.put(entry.getKey(), entry.getValue()); if (++i == MAX_DELETE_BATCH) break; } } GridCompoundFuture<Object, ?> fut = new GridCompoundFuture<>(); // Delegate to child folders. for (IgfsListingEntry entry : delListing.values()) { if (!cancelled) { if (entry.isDirectory()) deleteDirectory(id, entry.fileId()); else { IgfsFileInfo fileInfo = meta.info(entry.fileId()); if (fileInfo != null) { assert fileInfo.isFile(); fut.add(data.delete(fileInfo)); } } } else return; } fut.markInitialized(); // Wait for data cache to delete values before clearing meta cache. try { fut.get(); } catch (IgniteFutureCancelledCheckedException ignore) { // This future can be cancelled only due to IGFS shutdown. cancelled = true; return; } // Actual delete of folder content. Collection<IgniteUuid> delIds = meta.delete(id, delListing); if (delListing == listing && delListing.size() == delIds.size()) break; // All entries were deleted. } else break; // Entry was deleted concurrently. } }