/** @param entry Entry. */ @SuppressWarnings({"SynchronizationOnLocalVariableOrMethodParameter"}) void recheck(@Nullable GridCacheEntryEx entry) { if (entry == null) return; if (exchLog.isDebugEnabled()) exchLog.debug("Rechecking entry for completion [entry=" + entry + ", finFut=" + this + ']'); Collection<GridCacheMvccCandidate> cands = pendingLocks.get(entry.txKey()); if (cands != null) { synchronized (cands) { for (Iterator<GridCacheMvccCandidate> it = cands.iterator(); it.hasNext(); ) { GridCacheMvccCandidate cand = it.next(); // Check exclude ID again, as key could have been reassigned. if (cand.removed()) it.remove(); } if (cands.isEmpty()) pendingLocks.remove(entry.txKey()); if (pendingLocks.isEmpty()) { onDone(); if (exchLog.isDebugEnabled()) exchLog.debug("Finish lock future is done: " + this); } } } }
/** * @param topVer Topology version. * @param entries Entries. */ FinishLockFuture(Iterable<GridDistributedCacheEntry> entries, AffinityTopologyVersion topVer) { assert topVer.compareTo(AffinityTopologyVersion.ZERO) > 0; this.topVer = topVer; for (GridCacheEntryEx entry : entries) { // Either local or near local candidates. try { Collection<GridCacheMvccCandidate> locs = entry.localCandidates(); if (!F.isEmpty(locs)) { Collection<GridCacheMvccCandidate> cands = new ConcurrentLinkedQueue<>(); cands.addAll(F.view(locs, versionFilter())); if (!F.isEmpty(cands)) pendingLocks.put(entry.txKey(), cands); } } catch (GridCacheEntryRemovedException ignored) { if (exchLog.isDebugEnabled()) exchLog.debug( "Got removed entry when adding it to finish lock future (will ignore): " + entry); } } if (exchLog.isDebugEnabled()) exchLog.debug("Pending lock set [topVer=" + topVer + ", locks=" + pendingLocks + ']'); }