helix-core/src/main/java/org/apache/helix/controller/rebalancer/strategy/AutoRebalanceStrategy.java [646:832]:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      total += count;
    }
    return total;
  }

  /**
   * Compute a map of replica ids to state names
   * @return Map: replica id -> state name
   */
  private Map<Integer, String> generateStateMap() {
    int replicaId = 0;
    Map<Integer, String> stateMap = new HashMap<Integer, String>();
    for (String state : _states.keySet()) {
      Integer count = _states.get(state);
      for (int i = 0; i < count; i++) {
        stateMap.put(replicaId, state);
        replicaId++;
      }
    }
    return stateMap;
  }

  /**
   * A Node is an entity that can serve replicas. It has a capacity and knowledge
   * of replicas assigned to it, so it can decide if it can receive additional replicas.
   */
  class Node {
    public int currentlyAssigned;
    public int capacity;
    public boolean hasCeilingCapacity;
    private final String id;
    boolean isAlive;
    private final List<Replica> preferred;
    private final List<Replica> nonPreferred;
    private final Set<Replica> newReplicas;

    public Node(String id) {
      preferred = new ArrayList<Replica>();
      nonPreferred = new ArrayList<Replica>();
      newReplicas = new TreeSet<Replica>();
      currentlyAssigned = 0;
      isAlive = false;
      this.id = id;
    }

    /**
     * Check if this replica can be legally added to this node
     * @param replica The replica to test
     * @return true if the assignment can be made, false otherwise
     */
    public boolean canAdd(Replica replica) {
      if (currentlyAssigned >= capacity) {
        return false;
      }
      return canAddIfCapacity(replica);
    }

    /**
     * Check if this replica can be legally added to this node, provided that it has enough
     * capacity.
     * @param replica The replica to test
     * @return true if the assignment can be made, false otherwise
     */
    public boolean canAddIfCapacity(Replica replica) {
      if (!isAlive) {
        return false;
      }
      for (Replica r : preferred) {
        if (r.partition.equals(replica.partition)) {
          return false;
        }
      }
      for (Replica r : nonPreferred) {
        if (r.partition.equals(replica.partition)) {
          return false;
        }
      }
      return true;
    }

    /**
     * Receive a replica by stealing capacity from another Node
     * @param donor The node that has excess capacity
     * @param replica The replica to receive
     */
    public void steal(Node donor, Replica replica) {
      donor.hasCeilingCapacity = false;
      donor.capacity--;
      hasCeilingCapacity = true;
      capacity++;
      currentlyAssigned++;
      nonPreferred.add(replica);
      newReplicas.add(replica);
    }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder();
      sb.append("##########\nname=").append(id).append("\npreferred:").append(preferred.size())
          .append("\nnonpreferred:").append(nonPreferred.size());
      return sb.toString();
    }
  }

  /**
   * A Replica is a combination of a partition of the resource, the state the replica is in
   * and an identifier signifying a specific replica of a given partition and state.
   */
  class Replica implements Comparable<Replica> {
    private String partition;
    private int replicaId; // this is a partition-relative id
    private String format;

    public Replica(String partition, int replicaId) {
      this.partition = partition;
      this.replicaId = replicaId;
      this.format = this.partition + "|" + this.replicaId;
    }

    @Override
    public String toString() {
      return format;
    }

    @Override
    public boolean equals(Object that) {
      if (that instanceof Replica) {
        return this.format.equals(((Replica) that).format);
      }
      return false;
    }

    @Override
    public int hashCode() {
      return this.format.hashCode();
    }

    @Override
    public int compareTo(Replica that) {
      if (that instanceof Replica) {
        return this.format.compareTo(that.format);
      }
      return -1;
    }
  }

  /**
   * Interface for providing a custom approach to computing a replica's affinity to a node.
   */
  public interface ReplicaPlacementScheme {
    /**
     * Initialize global state
     * @param manager The instance to which this placement is associated
     */
    public void init(final HelixManager manager);

    /**
     * Given properties of this replica, determine the node it would prefer to be served by
     * @param partitionId The current partition
     * @param replicaId The current replica with respect to the current partition
     * @param numPartitions The total number of partitions
     * @param numReplicas The total number of replicas per partition
     * @param nodeNames A list of identifiers of all nodes, live and non-live
     * @return The name of the node that would prefer to serve this replica
     */
    public String getLocation(int partitionId, int replicaId, int numPartitions, int numReplicas,
        final List<String> nodeNames);
  }

  /**
   * Compute preferred placements based on a default strategy that assigns replicas to nodes as
   * evenly as possible while avoiding placing two replicas of the same partition on any node.
   */
  public static class DefaultPlacementScheme implements ReplicaPlacementScheme {
    @Override
    public void init(final HelixManager manager) {
      // do nothing since this is independent of the manager
    }

    @Override
    public String getLocation(int partitionId, int replicaId, int numPartitions, int numReplicas,
        final List<String> nodeNames) {
      int index;
      if (nodeNames.size() > numPartitions) {
        // assign replicas in partition order in case there are more nodes than partitions
        index = (partitionId + replicaId * numPartitions) % nodeNames.size();
      } else if (nodeNames.size() == numPartitions) {
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -



helix-core/src/main/java/org/apache/helix/controller/strategy/AutoRebalanceStrategy.java [558:744]:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      total += count;
    }
    return total;
  }

  /**
   * Compute a map of replica ids to state names
   * @return Map: replica id -> state name
   */
  private Map<Integer, String> generateStateMap() {
    int replicaId = 0;
    Map<Integer, String> stateMap = new HashMap<Integer, String>();
    for (String state : _states.keySet()) {
      Integer count = _states.get(state);
      for (int i = 0; i < count; i++) {
        stateMap.put(replicaId, state);
        replicaId++;
      }
    }
    return stateMap;
  }

  /**
   * A Node is an entity that can serve replicas. It has a capacity and knowledge
   * of replicas assigned to it, so it can decide if it can receive additional replicas.
   */
  class Node {
    public int currentlyAssigned;
    public int capacity;
    public boolean hasCeilingCapacity;
    private final String id;
    boolean isAlive;
    private final List<Replica> preferred;
    private final List<Replica> nonPreferred;
    private final Set<Replica> newReplicas;

    public Node(String id) {
      preferred = new ArrayList<Replica>();
      nonPreferred = new ArrayList<Replica>();
      newReplicas = new TreeSet<Replica>();
      currentlyAssigned = 0;
      isAlive = false;
      this.id = id;
    }

    /**
     * Check if this replica can be legally added to this node
     * @param replica The replica to test
     * @return true if the assignment can be made, false otherwise
     */
    public boolean canAdd(Replica replica) {
      if (currentlyAssigned >= capacity) {
        return false;
      }
      return canAddIfCapacity(replica);
    }

    /**
     * Check if this replica can be legally added to this node, provided that it has enough
     * capacity.
     * @param replica The replica to test
     * @return true if the assignment can be made, false otherwise
     */
    public boolean canAddIfCapacity(Replica replica) {
      if (!isAlive) {
        return false;
      }
      for (Replica r : preferred) {
        if (r.partition.equals(replica.partition)) {
          return false;
        }
      }
      for (Replica r : nonPreferred) {
        if (r.partition.equals(replica.partition)) {
          return false;
        }
      }
      return true;
    }

    /**
     * Receive a replica by stealing capacity from another Node
     * @param donor The node that has excess capacity
     * @param replica The replica to receive
     */
    public void steal(Node donor, Replica replica) {
      donor.hasCeilingCapacity = false;
      donor.capacity--;
      hasCeilingCapacity = true;
      capacity++;
      currentlyAssigned++;
      nonPreferred.add(replica);
      newReplicas.add(replica);
    }

    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder();
      sb.append("##########\nname=").append(id).append("\npreferred:").append(preferred.size())
          .append("\nnonpreferred:").append(nonPreferred.size());
      return sb.toString();
    }
  }

  /**
   * A Replica is a combination of a partition of the resource, the state the replica is in
   * and an identifier signifying a specific replica of a given partition and state.
   */
  class Replica implements Comparable<Replica> {
    private String partition;
    private int replicaId; // this is a partition-relative id
    private String format;

    public Replica(String partition, int replicaId) {
      this.partition = partition;
      this.replicaId = replicaId;
      this.format = this.partition + "|" + this.replicaId;
    }

    @Override
    public String toString() {
      return format;
    }

    @Override
    public boolean equals(Object that) {
      if (that instanceof Replica) {
        return this.format.equals(((Replica) that).format);
      }
      return false;
    }

    @Override
    public int hashCode() {
      return this.format.hashCode();
    }

    @Override
    public int compareTo(Replica that) {
      if (that instanceof Replica) {
        return this.format.compareTo(that.format);
      }
      return -1;
    }
  }

  /**
   * Interface for providing a custom approach to computing a replica's affinity to a node.
   */
  public interface ReplicaPlacementScheme {
    /**
     * Initialize global state
     * @param manager The instance to which this placement is associated
     */
    public void init(final HelixManager manager);

    /**
     * Given properties of this replica, determine the node it would prefer to be served by
     * @param partitionId The current partition
     * @param replicaId The current replica with respect to the current partition
     * @param numPartitions The total number of partitions
     * @param numReplicas The total number of replicas per partition
     * @param nodeNames A list of identifiers of all nodes, live and non-live
     * @return The name of the node that would prefer to serve this replica
     */
    public String getLocation(int partitionId, int replicaId, int numPartitions, int numReplicas,
        final List<String> nodeNames);
  }

  /**
   * Compute preferred placements based on a default strategy that assigns replicas to nodes as
   * evenly as possible while avoiding placing two replicas of the same partition on any node.
   */
  public static class DefaultPlacementScheme implements ReplicaPlacementScheme {
    @Override
    public void init(final HelixManager manager) {
      // do nothing since this is independent of the manager
    }

    @Override
    public String getLocation(int partitionId, int replicaId, int numPartitions, int numReplicas,
        final List<String> nodeNames) {
      int index;
      if (nodeNames.size() > numPartitions) {
        // assign replicas in partition order in case there are more nodes than partitions
        index = (partitionId + replicaId * numPartitions) % nodeNames.size();
      } else if (nodeNames.size() == numPartitions) {
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -



