Exemplo n.º 1
0
  /**
   * Adds future.
   *
   * @param fut Future.
   * @return {@code True} if added.
   */
  @SuppressWarnings({"SynchronizationOnLocalVariableOrMethodParameter"})
  public boolean addFuture(final GridCacheFuture<?> fut) {
    if (fut.isDone()) {
      fut.markNotTrackable();

      return true;
    }

    if (!fut.trackable()) return true;

    while (true) {
      Collection<GridCacheFuture<?>> old =
          futs.putIfAbsent(
              fut.version(),
              new ConcurrentLinkedDeque8<GridCacheFuture<?>>() {
                /** */
                private int hash;

                {
                  // Make sure that we add future to queue before
                  // adding queue to the map of futures.
                  add(fut);
                }

                @Override
                public int hashCode() {
                  if (hash == 0) hash = System.identityHashCode(this);

                  return hash;
                }

                @Override
                public boolean equals(Object obj) {
                  return obj == this;
                }
              });

      if (old != null) {
        boolean empty, dup = false;

        synchronized (old) {
          empty = old.isEmpty();

          if (!empty) dup = old.contains(fut);

          if (!empty && !dup) old.add(fut);
        }

        // Future is being removed, so we force-remove here and try again.
        if (empty) {
          if (futs.remove(fut.version(), old)) {
            if (log.isDebugEnabled())
              log.debug("Removed future list from futures map for lock version: " + fut.version());
          }

          continue;
        }

        if (dup) {
          if (log.isDebugEnabled())
            log.debug("Found duplicate future in futures map (will not add): " + fut);

          return false;
        }
      }

      // Handle version mappings.
      if (fut instanceof GridCacheMappedVersion) {
        GridCacheVersion from = ((GridCacheMappedVersion) fut).mappedVersion();

        if (from != null) mapVersion(from, fut.version());
      }

      if (log.isDebugEnabled()) log.debug("Added future to future map: " + fut);

      break;
    }

    // Close window in case of node is gone before the future got added to
    // the map of futures.
    for (ClusterNode n : fut.nodes()) {
      if (cctx.discovery().node(n.id()) == null) fut.onNodeLeft(n.id());
    }

    // Just in case if future was completed before it was added.
    if (fut.isDone()) removeFuture(fut);
    else onFutureAdded(fut);

    return true;
  }