public void initDB(String[] args) {

    final String servers = Args.valueOf(args, "-servers", "localhost");

    String propFile = Args.valueOf(args, "-props", "swiftsocial-test.props");
    Properties properties = Props.parseFile("swiftsocial", propFile);
    configBloatedCounters(properties);
    SafeLog.configure(properties);

    System.err.println("Populating db with users...");

    int numUsers = Props.intValue(properties, "swiftsocial.numUsers", 1000);

    final int NumUsers = Args.valueOf(args, "-users", numUsers);
    Workload.generateUsers(NumUsers);

    int threads = Args.valueOf(args, "-threads", 6);
    final int PARTITION_SIZE = 1000;
    int partitions = numUsers / PARTITION_SIZE + (numUsers % PARTITION_SIZE > 0 ? 1 : 0);
    ExecutorService pool = Executors.newFixedThreadPool(threads);

    final AtomicInteger counter = new AtomicInteger(0);
    for (int i = 0; i < partitions; i++) {
      int lo = i * PARTITION_SIZE, hi = (i + 1) * PARTITION_SIZE;
      final List<String> partition = Workload.getUserData().subList(lo, Math.min(hi, numUsers));
      pool.execute(
          new Runnable() {
            public void run() {
              SwiftOptions options = new SwiftOptions(servers, DCConstants.SURROGATE_PORT);
              options.setCacheUpdateProtocol(CacheUpdateProtocol.NO_CACHE_OR_UNCOORDINATED);
              SwiftSocialBenchmark.super.initUsers(options, partition, counter, NumUsers);
            }
          });
    }
    Threading.awaitTermination(pool, Integer.MAX_VALUE);
    Threading.sleep(5000);
    System.err.println("\nFinished populating db with users.");
  }
  public void doBenchmark(String[] args) {
    super.init(args);
    // IO.redirect("stdout.txt", "stderr.txt");
    final long startTime = System.currentTimeMillis();

    System.err.println(IP.localHostname() + "/ starting...");

    int concurrentSessions = Args.valueOf(args, "-threads", 1);
    String partitions = Args.valueOf(args, "-partition", "0/1");
    int site = Integer.valueOf(partitions.split("/")[0]);
    int numberOfSites = Integer.valueOf(partitions.split("/")[1]);
    // ASSUMPTION: concurrentSessions is the same at all sites
    int numberOfVirtualSites = numberOfSites * concurrentSessions;

    List<String> candidates = Args.subList(args, "-servers");
    server = ClosestDomain.closest2Domain(candidates, site);
    shepard = Args.valueOf(args, "-shepard", "");

    System.err.println(IP.localHostAddress() + " connecting to: " + server);

    super.populateWorkloadFromConfig();

    SafeLog.printlnComment("");
    SafeLog.printlnComment(String.format("\targs=%s", Arrays.asList(args)));
    SafeLog.printlnComment(String.format("\tsite=%s", site));
    SafeLog.printlnComment(String.format("\tnumberOfSites=%s", numberOfSites));
    SafeLog.printlnComment(String.format("\tthreads=%s", concurrentSessions));
    SafeLog.printlnComment(String.format("\tnumberOfVirtualSites=%s", numberOfVirtualSites));
    SafeLog.printlnComment(String.format("\tSurrogate=%s", server));
    SafeLog.printlnComment(String.format("\tShepard=%s", shepard));

    if (!shepard.isEmpty()) Shepard.sheepJoinHerd(shepard);

    // Kick off all sessions, throughput is limited by
    // concurrentSessions.
    final ExecutorService threadPool =
        Executors.newFixedThreadPool(concurrentSessions, Threading.factory("App"));

    final double sessionOpsPerMs =
        ((double) targetOpsPerSec / (double) concurrentSessions) / 1000.0;
    System.err.println("Spawning session threads.");
    for (int i = 0; i < concurrentSessions; i++) {
      final int sessionId = site * concurrentSessions + i;
      final Workload commands = getWorkloadFromConfig(sessionId, numberOfVirtualSites);
      threadPool.execute(
          new Runnable() {
            public void run() {
              // Randomize startup to avoid clients running all at the
              // same time; causes problems akin to DDOS symptoms.
              Threading.sleep(Sys.rg.nextInt(10000));
              SwiftSocialBenchmark.super.runClientSession(
                  Integer.toString(sessionId), commands, false, sessionOpsPerMs);
            }
          });
    }

    // report client progress every 10 seconds...
    final int PERIOD = 10;
    new PeriodicTask(0.0, 0.0 + PERIOD) {
      private int lastDone;

      public void run() {
        final int recentDone = commandsDone.get();
        final int throughput = (recentDone - lastDone) / PERIOD;
        lastDone = recentDone;
        System.err.printf(
            "Done: %s, throughput %d op/s\n",
            Progress.percentage(recentDone, totalCommands.get()), throughput);
      }
    };

    // Wait for all sessions.
    threadPool.shutdown();
    Threading.awaitTermination(threadPool, Integer.MAX_VALUE);

    System.err.println("Session threads completed.");
    System.err.println(
        "Throughput: "
            + totalCommands.get() * 1000 / (System.currentTimeMillis() - startTime)
            + " txns/s");
    System.exit(0);
  }
  public static void main(String[] args) {
    sys.Sys.init();

    SwiftSocialBenchmark instance = new SwiftSocialBenchmark();
    if (args.length == 0) {

      // DCSequencerServer.main(new String[] { "-name", "X", "-integrated"
      // });
      DCServer.main(new String[] {"-servers", "localhost", "-integrated"});

      args =
          new String[] {
            "-servers", "localhost", "-threads", "2", "-props", "swiftsocial-test.props"
          };
      SafeLog.configure(EnumSet.of(ReportType.APP_OP));
      instance.initDB(args);
      instance.doBenchmark(args);
      exit(0);
    }
    if (args[0].equals("-prepareDB")) {
      if (args.length != 3) {
        System.err.println(Arrays.asList(args));
        System.err.println("usage: -prepareDB dbName numUsers");
        System.exit(0);
      }
      // uses berkeleydb in sync mode to create a DB snapshot.
      // In folder db, default and default_seq need
      // to be renamed manually to 25k and 25k_seq
      DCSequencerServer.main(new String[] {"-sync", "-db", args[1], "-name", "X"});
      DCServer.main(new String[] {"-sync", "-db", args[1], "-servers", "localhost"});
      args = new String[] {"-servers", "localhost", "-users", args[2]};

      instance.initDB(args);

      Threading.sleep(60000);
      exit(0);
    }
    if (args[0].equals("-reloadDB")) {
      if (args.length != 3) {
        System.err.println(Arrays.asList(args));
        System.err.println("usage: -reloadDB dbName propfile");
        System.exit(0);
      }
      // assumes there is db/25k and db/25k_seq folders with the prepared
      // db snapshot, eg., for args[1] == 25k
      System.err.println(Arrays.asList(args));
      DCSequencerServer.main(new String[] {"-rdb", args[1], "-db", "-name", "X"});
      DCServer.main(new String[] {"-rdb", args[1], "-servers", "localhost"});
      args = new String[] {"-servers", "localhost", "-props", args[2]};

      instance.doBenchmark(args);
      exit(0);
    }
    if (args[0].equals("init")) {
      instance.initDB(args);
      exit(0);
    }
    if (args[0].equals("run")) {
      instance.doBenchmark(args);
      exit(0);
    }
  }