private static void fillDatabase(MetricRegistry registry, NamedBlobDb namedBlobDb, ScheduledExecutorService executor,
      AccountService accountService, long existingRows, long targetRows, int numThreads) throws Exception {
    long remainingRows = targetRows - existingRows;
    System.out.println("Existing number of rows: " + existingRows + ". Target number of rows: " + targetRows
        + ". Number of rows to insert: " + remainingRows);
    AtomicLong trackingRow = new AtomicLong();
    long numberOfInsertPerWorker = remainingRows / numThreads;
    List<Future<?>> futures = new ArrayList<>();
    for (int i = 0; i < numThreads; i++) {
      long num = numberOfInsertPerWorker;
      if (i == numThreads - 1) {
        num = remainingRows - i * numberOfInsertPerWorker;
      }
      futures.add(executor.submit(new RowFillWorker(i, namedBlobDb, accountService, num, trackingRow)));
    }
    AtomicBoolean stop = new AtomicBoolean(false);
    executor.submit(() -> {
      try {
        while (!stop.get()) {
          System.out.println(trackingRow.get() + " rows has been inserted");
          Thread.sleep(1000);
        }
      } catch (Exception e) {
      }
    });
    for (Future<?> future : futures) {
      future.get();
    }
    System.out.println("All the RowFillWorkers are finished");
    stop.set(true);
    printHistogramMetric(registry, "com.github.ambry.named.MySqlNamedBlobDb.NamedBlobPutTimeInMs");
  }
Fill database(table) with rows so we can reach the target number of rows.
@param registry The {@link MetricRegistry} object.
@param namedBlobDb The {@link NamedBlobDb} object.
@param executor The {@link ScheduledExecutorService} object.
@param accountService The {@link AccountService} object.
@param existingRows The number of existing rows.
@param targetRows The number of target rows.
@param numThreads The number of threads for insert database rows.
@throws Exception
ambry-tools/src/main/java/com/github/ambry/tools/perf/NamedBlobMysqlDatabasePerf.java