/** Assigns local lock. */ private void reassign() { GridCacheMvccCandidate firstRmt = null; if (rmts != null) { for (GridCacheMvccCandidate cand : rmts) { if (firstRmt == null) firstRmt = cand; // If there is a remote owner, then local cannot be an owner, // so no reassignment happens. if (cand.owner()) return; } } if (locs != null) { boolean first = true; ListIterator<GridCacheMvccCandidate> it = locs.listIterator(); while (it.hasNext()) { GridCacheMvccCandidate cand = it.next(); if (first) { if (cand.read()) { if (cand.ready() && !cand.owner()) cand.setOwner(); while (it.hasNext()) { cand = it.next(); if (!cand.read()) break; if (cand.ready() && !cand.owner()) cand.setOwner(); } return; } else if (cand.serializable()) { if (cand.owner() || !cand.ready()) return; cand.setOwner(); return; } first = false; } if (cand.owner()) return; if (cand.ready()) { GridCacheMvccCandidate prev = nonRollbackPrevious(cand); // If previous has not been acquired, this candidate cannot acquire lock either, // so we move on to the next one. if (prev != null && !prev.owner()) continue; boolean assigned = false; if (!cctx.isNear() && firstRmt != null && cand.version().isGreater(firstRmt.version())) { // Check previous candidates for 2 cases: // 1. If this candidate is waiting for a smaller remote version, // then we must check if previous candidate is the owner and // has the same remote candidate version. In that case, we can // safely set this candidate to owner as well. // 2. If this candidate is waiting for a smaller remote version, // then we must check if previous candidate is the owner and // any of the local candidates with versions smaller than first // remote version have the same key as the previous owner. In // that case, we can safely set this candidate to owner as well. while (prev != null && prev.owner()) { for (GridCacheMvccCandidate c : prev.parent().remoteMvccSnapshot()) { if (c.version().equals(firstRmt.version())) { cand.setOwner(); assigned = true; break; // For. } } if (!assigned) { for (GridCacheMvccCandidate c : locs) { if (c == cand || c.version().isGreater(firstRmt.version())) break; for (GridCacheMvccCandidate p = c.previous(); p != null; p = p.previous()) { if (p.key().equals(prev.key())) { cand.setOwner(); assigned = true; break; // For. } } if (assigned) break; // For. } } if (assigned) break; // While. prev = prev.previous(); } } if (!assigned) { if (!cctx.isNear() && firstRmt != null) { if (cand.version().isLess(firstRmt.version())) { assert !cand.nearLocal(); cand.setOwner(); assigned = true; } } else { cand.setOwner(); assigned = true; } } if (assigned) { assert !cand.serializable() : cand; it.remove(); // Owner must be first in the list. locs.addFirst(cand); } return; } } } }