/** {@inheritDoc} */
  @Override
  public void printMemoryStats() {
    X.println(">>> ");
    X.println(">>> Grid memory stats [grid=" + gridName() + ']');

    for (GridComponent comp : comps) comp.printMemoryStats();
  }
  /** {@inheritDoc} */
  @Override
  public void printMemoryStats() {
    super.printMemoryStats();

    X.println(">>>   threadsSize: " + threads.size());
    X.println(">>>   futsSize: " + futs.size());
  }
  /** {@inheritDoc} */
  @Override
  public void printMemoryStats(int threshold) {
    X.println(
        ">>>  Cache partition topology stats [grid="
            + cctx.gridName()
            + ", cache="
            + cctx.name()
            + ']');

    for (GridDhtLocalPartition part : locParts.values()) {
      int size = part.size();

      if (size >= threshold)
        X.println(">>>   Local partition [part=" + part.id() + ", size=" + size + ']');
    }
  }
 /** {@inheritDoc} */
 @Override
 public void printMemoryStats() {
   X.println(">>> ");
   X.println(">>> Mvcc manager memory stats [grid=" + cctx.gridName() + ']');
   X.println(">>>   rmvLocksSize: " + rmvLocks.size());
   X.println(">>>   dhtLocCandsSize: " + dhtLocCands.size());
   X.println(">>>   lockedSize: " + locked.size());
   X.println(">>>   futsSize: " + futs.size());
   X.println(">>>   near2dhtSize: " + near2dht.size());
   X.println(">>>   finishFutsSize: " + finishFuts.size());
 }
 /**
  * @param log Logger.
  * @param time Time.
  * @param msg Message.
  */
 private static void log0(@Nullable IgniteLogger log, long time, String msg) {
   if (log != null) {
     if (log.isDebugEnabled()) log.debug(msg);
     else log.warning(msg);
   } else
     X.println(
         String.format(
             "[%s][%s]%s",
             DEBUG_DATE_FMT.get().format(time), Thread.currentThread().getName(), msg));
 }
  /** @throws Exception If failed. */
  public void testCompact() throws Exception {
    File file = new File(UUID.randomUUID().toString());

    X.println("file: " + file.getPath());

    FileSwapSpaceSpi.SwapFile f = new FileSwapSpaceSpi.SwapFile(file, 8);

    Random rnd = new Random();

    ArrayList<FileSwapSpaceSpi.SwapValue> arr = new ArrayList<>();

    int size = 0;

    for (int a = 0; a < 100; a++) {
      FileSwapSpaceSpi.SwapValue[] vals = new FileSwapSpaceSpi.SwapValue[1 + rnd.nextInt(10)];

      int size0 = 0;

      for (int i = 0; i < vals.length; i++) {
        byte[] bytes = new byte[1 + rnd.nextInt(49)];

        rnd.nextBytes(bytes);

        size0 += bytes.length;

        vals[i] = new FileSwapSpaceSpi.SwapValue(bytes);

        arr.add(vals[i]);
      }

      f.write(new FileSwapSpaceSpi.SwapValues(vals, size0), 1);

      size += size0;

      assertEquals(f.length(), size);
      assertEquals(file.length(), size);
    }

    int i = 0;

    for (FileSwapSpaceSpi.SwapValue val : arr) assertEquals(val.idx(), ++i);

    i = 0;

    for (int cnt = arr.size() / 2; i < cnt; i++) {

      FileSwapSpaceSpi.SwapValue v = arr.remove(rnd.nextInt(arr.size()));

      assertTrue(f.tryRemove(v.idx(), v));
    }

    int hash0 = 0;

    for (FileSwapSpaceSpi.SwapValue val : arr) hash0 += Arrays.hashCode(val.readValue(f.readCh));

    ArrayList<T2<ByteBuffer, ArrayDeque<FileSwapSpaceSpi.SwapValue>>> bufs = new ArrayList();

    for (; ; ) {
      ArrayDeque<FileSwapSpaceSpi.SwapValue> que = new ArrayDeque<>();

      ByteBuffer buf = f.compact(que, 1024);

      if (buf == null) break;

      bufs.add(new T2(buf, que));
    }

    f.delete();

    int hash1 = 0;

    for (FileSwapSpaceSpi.SwapValue val : arr) hash1 += Arrays.hashCode(val.value(null));

    assertEquals(hash0, hash1);

    File file0 = new File(UUID.randomUUID().toString());

    FileSwapSpaceSpi.SwapFile f0 = new FileSwapSpaceSpi.SwapFile(file0, 8);

    for (T2<ByteBuffer, ArrayDeque<FileSwapSpaceSpi.SwapValue>> t : bufs)
      f0.write(t.get2(), t.get1(), 1);

    int hash2 = 0;

    for (FileSwapSpaceSpi.SwapValue val : arr) hash2 += Arrays.hashCode(val.readValue(f0.readCh));

    assertEquals(hash2, hash1);
  }
    /** {@inheritDoc} */
    @Override
    public String execute() {
      assert taskSes != null;

      assert startLatch != null;

      assert read1Latch != null;
      assert read2Latch != null;
      assert read3Latch != null;

      assert read1FinishedLatch != null;
      assert read2FinishedLatch != null;
      assert read3FinishedLatch != null;

      assert rmvLatch != null;

      startLatch.countDown();

      try {
        startLatch.await();
      } catch (InterruptedException e) {
        throw new IgniteException("Thread has been interrupted.", e);
      }

      X.println(">>> Consumer started.");

      try {
        read1Latch.await();
      } catch (InterruptedException e) {
        throw new IgniteException("Thread has been interrupted.", e);
      }

      // Test that checkpoints were saved properly.
      assertWithRetries(
          new GridAbsClosureX() {
            @Override
            public void applyx() {
              assert GLOBAL_VAL.equals(taskSes.loadCheckpoint(GLOBAL_KEY));
              assert SES_VAL.equals(taskSes.loadCheckpoint(SES_KEY));
            }
          });

      read1FinishedLatch.countDown();

      try {
        read2Latch.await();
      } catch (InterruptedException e) {
        throw new IgniteException("Thread has been interrupted.", e);
      }

      // Test that checkpoints were not overwritten.
      assertWithRetries(
          new GridAbsClosureX() {
            @Override
            public void applyx() {
              assert GLOBAL_VAL.equals(taskSes.loadCheckpoint(GLOBAL_KEY));
              assert SES_VAL.equals(taskSes.loadCheckpoint(SES_KEY));
            }
          });

      read2FinishedLatch.countDown();

      try {
        read3Latch.await();
      } catch (InterruptedException e) {
        throw new IgniteException("Thread has been interrupted.", e);
      }

      assertWithRetries(
          new GridAbsClosureX() {
            @Override
            public void applyx() {
              assertEquals(SES_VAL_OVERWRITTEN, taskSes.loadCheckpoint(GLOBAL_KEY));
              assertEquals(GLOBAL_VAL_OVERWRITTEN, taskSes.loadCheckpoint(SES_KEY));
            }
          });

      read3FinishedLatch.countDown();

      try {
        rmvLatch.await();
      } catch (InterruptedException e) {
        throw new IgniteException("Thread has been interrupted.", e);
      }
      // Check checkpoints are actually removed.
      assert !taskSes.removeCheckpoint(GLOBAL_KEY);
      assert !taskSes.removeCheckpoint(SES_KEY);

      assertWithRetries(
          new GridAbsClosureX() {
            @Override
            public void applyx() {
              assert taskSes.loadCheckpoint(GLOBAL_KEY) == null;
              assert taskSes.loadCheckpoint(SES_KEY) == null;
            }
          });

      return null;
    }
    /** {@inheritDoc} */
    @Override
    public String execute() {
      assert ignite != null;
      assert taskSes != null;

      assert startLatch != null;

      assert read1Latch != null;
      assert read2Latch != null;
      assert read3Latch != null;

      assert read1FinishedLatch != null;
      assert read2FinishedLatch != null;
      assert read3FinishedLatch != null;

      assert rmvLatch != null;

      startLatch.countDown();

      try {
        startLatch.await();
      } catch (InterruptedException e) {
        throw new IgniteException("Thread has been interrupted.", e);
      }

      X.println(">>> Producer started.");

      taskSes.saveCheckpoint(GLOBAL_KEY, GLOBAL_VAL, GLOBAL_SCOPE, 0);
      taskSes.saveCheckpoint(SES_KEY, SES_VAL, SESSION_SCOPE, 0);

      read1Latch.countDown();

      try {
        read1FinishedLatch.await();
      } catch (InterruptedException e) {
        throw new IgniteException("Thread has been interrupted.", e);
      }

      // No retries here as other thread should have seen checkpoint already.
      assert GLOBAL_VAL.equals(taskSes.loadCheckpoint(GLOBAL_KEY));
      assert SES_VAL.equals(taskSes.loadCheckpoint(SES_KEY));

      taskSes.saveCheckpoint(GLOBAL_KEY, SES_VAL + "-notoverwritten", GLOBAL_SCOPE, 0, false);
      taskSes.saveCheckpoint(SES_KEY, GLOBAL_VAL + "-notoverwritten", SESSION_SCOPE, 0, false);

      read2Latch.countDown();

      try {
        read2FinishedLatch.await();
      } catch (InterruptedException e) {
        throw new IgniteException("Thread has been interrupted.", e);
      }

      assert GLOBAL_VAL.equals(taskSes.loadCheckpoint(GLOBAL_KEY));
      assert SES_VAL.equals(taskSes.loadCheckpoint(SES_KEY));

      // Swap values.
      taskSes.saveCheckpoint(GLOBAL_KEY, SES_VAL_OVERWRITTEN, GLOBAL_SCOPE, 0, true);
      taskSes.saveCheckpoint(SES_KEY, GLOBAL_VAL_OVERWRITTEN, SESSION_SCOPE, 0, true);

      read3Latch.countDown();

      try {
        read3FinishedLatch.await();
      } catch (InterruptedException e) {
        throw new IgniteException("Thread has been interrupted.", e);
      }

      assert SES_VAL_OVERWRITTEN.equals(taskSes.loadCheckpoint(GLOBAL_KEY));
      assert GLOBAL_VAL_OVERWRITTEN.equals(taskSes.loadCheckpoint(SES_KEY));

      // Remove checkpoints.
      assert taskSes.removeCheckpoint(GLOBAL_KEY);
      assert taskSes.removeCheckpoint(SES_KEY);

      // Check checkpoints are actually removed.
      assert !taskSes.removeCheckpoint(GLOBAL_KEY);
      assert !taskSes.removeCheckpoint(SES_KEY);

      rmvLatch.countDown();

      assertWithRetries(
          new GridAbsClosureX() {
            @Override
            public void applyx() {
              assert taskSes.loadCheckpoint(GLOBAL_KEY) == null;
              assert taskSes.loadCheckpoint(SES_KEY) == null;
            }
          });

      return null;
    }