private void load() {
    parallelism = (Map<String, Integer>) loadObject("parallelism");
    iteration = (Integer) loadObject("iteration");
    algorithm.load();

    // If inactive after rebalance, reactivate
    String status = topologyStatus();
    if (status != null && status.equals("INACTIVE")) {
      activate();
    }
  }
  public void update(double throughput, Map<String, ComponentStatistics> statistics) {
    String status = topologyStatus();
    LOG.info("Throughput: " + throughput);
    LOG.info("Topology Status: " + status);

    // wait sufficiently after rebalancing to run the algorithm again
    if (status != null) {
      if (status.equals("REBALANCING")) {
        updateCounter = -5;
      }
      if (status.equals("INACTIVE")) {
        updateCounter = -5;
      }
    }

    LOG.info("updateCounter = " + updateCounter);

    if (updateCounter > 15) {
      newThroughputs.add(throughput);
    }
    updateCounter++;

    int n = newThroughputs.size();
    if (n > 10) {
      boolean stable =
          !significantIncrease(
              newThroughputs.subList(n - 10, n - 5), newThroughputs.subList(n - 5, n), 0.6);

      LOG.info("Throughputs! " + newThroughputs);
      LOG.info("stable = " + stable);

      if (stable) {
        // truncate the newThroughputs
        newThroughputs = new ArrayList<Double>(newThroughputs.subList(n - 10, n));
        newThroughput = mean(newThroughputs);
        LOG.info("Final Throughput: " + newThroughput);
        printStatistics(statistics);
        //
        iteration++;
        algorithm.run(statistics);

        newThroughputs = new ArrayList<Double>();
        updateCounter = 0;
      }
    }
  }
 public AlgorithmState(IFeedbackAlgorithm algorithm) {
   this.algorithm = algorithm;
   algorithm.setState(this);
   timer = new Timer();
 }
 // Save algorithm state to zookeeper
 public void save() {
   saveObject("parallelism", parallelism);
   saveObject("iteration", iteration);
   algorithm.save();
 }