Esempio n. 1
0
  /**
   * For all remote candidates standing behind the candidate being salvaged marks their transactions
   * as system invalidate and marks these candidates as owned and used.
   *
   * @param ver Version to salvage.
   */
  public void salvageRemote(GridCacheVersion ver) {
    assert ver != null;

    GridCacheMvccCandidate cand = candidate(rmts, ver);

    if (cand != null) {
      assert rmts != null;
      assert !rmts.isEmpty();

      for (Iterator<GridCacheMvccCandidate> iter = rmts.iterator(); iter.hasNext(); ) {
        GridCacheMvccCandidate rmt = iter.next();

        // For salvaged candidate doneRemote will be called explicitly.
        if (rmt == cand) break;

        // Only Near and DHT remote candidates should be released.
        assert !rmt.nearLocal();

        IgniteInternalTx tx = cctx.tm().tx(rmt.version());

        if (tx != null) {
          tx.systemInvalidate(true);

          rmt.setOwner();
          rmt.setUsed();
        } else iter.remove();
      }
    }
  }
Esempio n. 2
0
  /**
   * Local release.
   *
   * @param threadId ID of the thread.
   * @return Removed candidate.
   */
  @Nullable
  public GridCacheMvccCandidate releaseLocal(long threadId) {
    CacheLockCandidates owners = localOwners();

    // Release had no effect.
    if (owners == null) return null;

    GridCacheMvccCandidate owner = null;

    for (int i = 0; i < owners.size(); i++) {
      GridCacheMvccCandidate owner0 = owners.candidate(i);

      if (owner0.threadId() == threadId) {
        owner = owner0;

        break;
      }
    }

    if (owner != null) {
      owner.setUsed();

      remove0(owner.version(), true);

      return owner;
    } else return null;
  }
Esempio n. 3
0
  /**
   * Removes all candidates for node.
   *
   * @param nodeId Node ID.
   * @return Current owner.
   */
  @Nullable
  public CacheLockCandidates removeExplicitNodeCandidates(UUID nodeId) {
    if (rmts != null) {
      for (Iterator<GridCacheMvccCandidate> it = rmts.iterator(); it.hasNext(); ) {
        GridCacheMvccCandidate cand = it.next();

        if (!cand.tx() && (nodeId.equals(cand.nodeId()) || nodeId.equals(cand.otherNodeId()))) {
          cand.setUsed(); // Mark as used to be consistent.
          cand.setRemoved();

          it.remove();
        }
      }

      if (rmts.isEmpty()) rmts = null;
    }

    if (locs != null) {
      for (Iterator<GridCacheMvccCandidate> it = locs.iterator(); it.hasNext(); ) {
        GridCacheMvccCandidate cand = it.next();

        if (!cand.tx() && nodeId.equals(cand.otherNodeId()) && cand.dhtLocal()) {
          cand.setUsed(); // Mark as used to be consistent.
          cand.setRemoved();

          it.remove();
        }
      }

      if (locs.isEmpty()) locs = null;
    }

    reassign();

    return allOwners();
  }
Esempio n. 4
0
  /**
   * Sets remote candidate to done.
   *
   * @param ver Version.
   * @param pending Pending versions.
   * @param committed Committed versions.
   * @param rolledback Rolledback versions.
   * @return Lock owner.
   */
  @Nullable
  public CacheLockCandidates doneRemote(
      GridCacheVersion ver,
      Collection<GridCacheVersion> pending,
      Collection<GridCacheVersion> committed,
      Collection<GridCacheVersion> rolledback) {
    assert ver != null;

    if (log.isDebugEnabled())
      log.debug("Setting remote candidate to done [mvcc=" + this + ", ver=" + ver + "]");

    // Check remote candidate.
    GridCacheMvccCandidate cand = candidate(rmts, ver);

    if (cand != null) {
      assert rmts != null;
      assert !rmts.isEmpty();
      assert !cand.local() : "Remote candidate is marked as local: " + cand;
      assert !cand.nearLocal() : "Remote candidate is marked as near local: " + cand;

      cand.setOwner();
      cand.setUsed();

      List<GridCacheMvccCandidate> mvAfter = null;

      for (ListIterator<GridCacheMvccCandidate> it = rmts.listIterator(); it.hasNext(); ) {
        GridCacheMvccCandidate c = it.next();

        assert !c.nearLocal() : "Remote candidate marked as near local: " + c;

        if (c == cand) {
          if (mvAfter != null) for (GridCacheMvccCandidate mv : mvAfter) it.add(mv);

          break;
        } else if (!committed.contains(c.version())
            && !rolledback.contains(c.version())
            && pending.contains(c.version())) {
          it.remove();

          if (mvAfter == null) mvAfter = new LinkedList<>();

          mvAfter.add(c);
        }
      }
    }

    return allOwners();
  }
Esempio n. 5
0
  /**
   * Removes candidate from collection.
   *
   * @param col Collection.
   * @param ver Version of the candidate to remove.
   * @return {@code True} if candidate was removed.
   */
  private boolean remove0(Collection<GridCacheMvccCandidate> col, GridCacheVersion ver) {
    if (col != null) {
      for (Iterator<GridCacheMvccCandidate> it = col.iterator(); it.hasNext(); ) {
        GridCacheMvccCandidate cand = it.next();

        if (cand.version().equals(ver)) {
          cand.setUsed();
          cand.setRemoved();

          it.remove();

          reassign();

          return true;
        }
      }
    }

    return false;
  }
Esempio n. 6
0
  /**
   * Moves completed candidates right before the base one. Note that if base is not found, then
   * nothing happens and {@code false} is returned.
   *
   * @param baseVer Base version.
   * @param committedVers Committed versions relative to base.
   * @param rolledbackVers Rolled back versions relative to base.
   */
  public void orderCompleted(
      GridCacheVersion baseVer,
      Collection<GridCacheVersion> committedVers,
      Collection<GridCacheVersion> rolledbackVers) {
    assert baseVer != null;

    if (rmts != null && !F.isEmpty(committedVers)) {
      Deque<GridCacheMvccCandidate> mvAfter = null;

      int maxIdx = -1;

      for (ListIterator<GridCacheMvccCandidate> it = rmts.listIterator(rmts.size());
          it.hasPrevious(); ) {
        GridCacheMvccCandidate cur = it.previous();

        if (!cur.version().equals(baseVer) && committedVers.contains(cur.version())) {
          cur.setOwner();

          assert localOwners() == null || localOwner().nearLocal()
              : "Cannot not have local owner and "
                  + "remote completed transactions at the same time [baseVer="
                  + baseVer
                  + ", committedVers="
                  + committedVers
                  + ", rolledbackVers="
                  + rolledbackVers
                  + ", localOwner="
                  + localOwner()
                  + ", locs="
                  + locs
                  + ", rmts="
                  + rmts
                  + ']';

          if (maxIdx < 0) maxIdx = it.nextIndex();
        } else if (maxIdx >= 0 && cur.version().isGreaterEqual(baseVer)) {
          if (--maxIdx >= 0) {
            if (mvAfter == null) mvAfter = new LinkedList<>();

            it.remove();

            mvAfter.addFirst(cur);
          }
        }

        // If base is completed, then set it to owner too.
        if (!cur.owner() && cur.version().equals(baseVer) && committedVers.contains(cur.version()))
          cur.setOwner();
      }

      if (maxIdx >= 0 && mvAfter != null) {
        ListIterator<GridCacheMvccCandidate> it = rmts.listIterator(maxIdx + 1);

        for (GridCacheMvccCandidate cand : mvAfter) it.add(cand);
      }

      // Remove rolled back versions.
      if (!F.isEmpty(rolledbackVers)) {
        for (Iterator<GridCacheMvccCandidate> it = rmts.iterator(); it.hasNext(); ) {
          GridCacheMvccCandidate cand = it.next();

          if (rolledbackVers.contains(cand.version())) {
            cand.setUsed(); // Mark as used to be consistent, even though we are about to remove it.

            it.remove();
          }
        }

        if (rmts.isEmpty()) rmts = null;
      }
    }
  }