/**
     * Waits until total number of events processed is equal or greater then argument passed.
     *
     * @param cnt Number of events to wait.
     * @param timeout Timeout to wait.
     * @return {@code True} if successfully waited, {@code false} if timeout happened.
     * @throws InterruptedException If thread is interrupted.
     */
    public synchronized boolean awaitEvents(int cnt, long timeout) throws InterruptedException {
      long start = U.currentTimeMillis();

      long now = start;

      while (start + timeout > now) {
        if (evtCnt >= cnt) return true;

        wait(start + timeout - now);

        now = U.currentTimeMillis();
      }

      return false;
    }
  /** @throws Exception If failed. */
  private void doTest() throws Exception {
    System.gc();
    System.gc();
    System.gc();

    try {
      useCache = true;

      startGridsMultiThreaded(GRID_CNT);

      useCache = false;

      Ignite ignite = startGrid();

      final IgniteDataStreamer<Integer, String> ldr = ignite.dataStreamer(null);

      ldr.perNodeBufferSize(8192);
      ldr.receiver(DataStreamerCacheUpdaters.<Integer, String>batchedSorted());
      ldr.autoFlushFrequency(0);

      final LongAdder8 cnt = new LongAdder8();

      long start = U.currentTimeMillis();

      Thread t =
          new Thread(
              new Runnable() {
                @SuppressWarnings("BusyWait")
                @Override
                public void run() {
                  while (true) {
                    try {
                      Thread.sleep(10000);
                    } catch (InterruptedException ignored) {
                      break;
                    }

                    info(">>> Adds/sec: " + cnt.sumThenReset() / 10);
                  }
                }
              });

      t.setDaemon(true);

      t.start();

      int threadNum = 2; // Runtime.getRuntime().availableProcessors();

      multithreaded(
          new Callable<Object>() {
            @SuppressWarnings("InfiniteLoopStatement")
            @Override
            public Object call() throws Exception {
              ThreadLocalRandom8 rnd = ThreadLocalRandom8.current();

              while (true) {
                int i = rnd.nextInt(ENTRY_CNT);

                ldr.addData(i, vals[rnd.nextInt(vals.length)]);

                cnt.increment();
              }
            }
          },
          threadNum,
          "loader");

      info("Closing loader...");

      ldr.close(false);

      long duration = U.currentTimeMillis() - start;

      info("Finished performance test. Duration: " + duration + "ms.");
    } finally {
      stopAllGrids();
    }
  }