/**
   * Register a tree for the given request to be compared to the appropriate trees in
   * Stage.ANTIENTROPY when they become available.
   */
  private void rendezvous(TreeRequest request, MerkleTree tree) {
    RepairSession session = sessions.get(request.sessionid);
    if (session == null) {
      logger.warn(
          "Got a merkle tree response for unknown repair session {}: either this node has been restarted since the session was started, or the session has been interrupted for an unknown reason. ",
          request.sessionid);
      return;
    }

    RepairSession.RepairJob job = session.jobs.peek();
    if (job == null) {
      assert session.terminated();
      return;
    }

    logger.info(
        String.format(
            "[repair #%s] Received merkle tree for %s from %s",
            session.getName(), request.cf.right, request.endpoint));

    if (job.addTree(request, tree) == 0) {
      logger.debug("All trees received for " + session.getName() + "/" + request.cf.right);
      job.submitDifferencers();

      // This job is complete, switching to next in line (note that only
      // one thread will can ever do this)
      session.jobs.poll();
      RepairSession.RepairJob nextJob = session.jobs.peek();
      if (nextJob == null)
        // We are done with this repair session as far as differencing
        // is considern. Just inform the session
        session.differencingDone.signalAll();
      else nextJob.sendTreeRequests();
    }
  }
  /**
   * Register a tree for the given request to be compared to the appropriate trees in
   * Stage.ANTIENTROPY when they become available.
   */
  private void rendezvous(TreeRequest request, MerkleTree tree) {
    RepairSession session = sessions.get(request.sessionid);
    assert session != null;

    RepairSession.RepairJob job = session.jobs.peek();
    assert job != null : "A repair should have at least some jobs scheduled";

    if (job.addTree(request, tree) == 0) {
      logger.debug("All trees received for " + session.getName() + "/" + request.cf.right);
      job.submitDifferencers();

      // This job is complete, switching to next in line (note that only
      // one thread will can ever do this)
      session.jobs.poll();
      RepairSession.RepairJob nextJob = session.jobs.peek();
      if (nextJob == null)
        // We are done with this repair session as far as differencing
        // is considern. Just inform the session
        session.differencingDone.signalAll();
      else nextJob.sendTreeRequests();
    }
  }
 public void terminateSessions() {
   for (RepairSession session : sessions.values()) {
     session.forceShutdown();
   }
 }