/** @throws Exception If failed. */
  public void testInvalidateFlag() throws Exception {
    GridEx g0 = grid(0);

    GridCache<String, String> cache = g0.cache(PARTITIONED_CACHE_NAME);

    String key = null;

    for (int i = 0; i < 10_000; i++) {
      if (!cache.affinity().isPrimaryOrBackup(g0.localNode(), String.valueOf(i))) {
        key = String.valueOf(i);

        break;
      }
    }

    assertNotNull(key);

    cache.put(key, key); // Create entry in near cache, it is invalidated if INVALIDATE flag is set.

    assertNotNull(cache.peek(key));

    GridClientData d = client.data(PARTITIONED_CACHE_NAME);

    d.flagsOn(GridClientCacheFlag.INVALIDATE).put(key, "zzz");

    for (Grid g : G.allGrids()) {
      cache = g.cache(PARTITIONED_CACHE_NAME);

      if (cache.affinity().isPrimaryOrBackup(g.localNode(), key))
        assertEquals("zzz", cache.peek(key));
      else assertNull(cache.peek(key));
    }
  }
  /** {@inheritDoc} */
  @Nullable
  @Override
  public Map<? extends GridComputeJob, GridNode> map(
      List<GridNode> subgrid, @Nullable GridBiTuple<Set<UUID>, A> arg) throws GridException {
    assert arg != null;
    assert arg.get1() != null;

    start = U.currentTimeMillis();

    boolean debug = debugState(g);

    if (debug) logStart(g.log(), getClass(), start);

    Set<UUID> nodeIds = arg.get1();

    Map<GridComputeJob, GridNode> map = U.newHashMap(nodeIds.size());

    try {
      taskArg = arg.get2();

      for (GridNode node : subgrid) if (nodeIds.contains(node.id())) map.put(job(taskArg), node);

      return map;
    } finally {
      if (debug) logMapped(g.log(), getClass(), map.values());
    }
  }
 /** {@inheritDoc} */
 @Nullable
 @Override
 public final R reduce(List<GridComputeJobResult> results) throws GridException {
   try {
     return reduce0(results);
   } finally {
     if (debugState(g)) logFinish(g.log(), getClass(), start);
   }
 }
  /**
   * @param seq Start/stop sequence.
   * @throws Exception If failed.
   */
  private void checkSequence0(boolean[] seq) throws Exception {
    try {
      startGrid(0);

      TreeSet<Integer> started = new TreeSet<>();

      started.add(0);

      int topVer = 1;

      for (boolean start : seq) {
        if (start) {
          int nextIdx = nextIndex(started);

          startGrid(nextIdx);

          started.add(nextIdx);
        } else {
          int idx = started.last();

          stopGrid(idx);

          started.remove(idx);
        }

        topVer++;

        info("Grid 0: " + grid(0).localNode().id());

        ((GridKernal) grid(0))
            .internalCache()
            .context()
            .affinity()
            .affinityReadyFuture(topVer)
            .get();

        for (int i : started) {
          if (i != 0) {
            GridEx grid = grid(i);

            ((GridKernal) grid)
                .internalCache()
                .context()
                .affinity()
                .affinityReadyFuture(topVer)
                .get();

            info("Grid " + i + ": " + grid.localNode().id());

            for (int part = 0; part < parts; part++) {
              List<GridNode> firstNodes =
                  (List<GridNode>)
                      grid(0).cache(null).affinity().mapPartitionToPrimaryAndBackups(part);

              List<GridNode> secondNodes =
                  (List<GridNode>)
                      grid.cache(null).affinity().mapPartitionToPrimaryAndBackups(part);

              assertEquals(firstNodes.size(), secondNodes.size());

              for (int n = 0; n < firstNodes.size(); n++)
                assertEquals(firstNodes.get(n), secondNodes.get(n));
            }
          }
        }
      }
    } finally {
      stopAllGrids();
    }
  }