helix-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From kisho...@apache.org
Subject [1/2] [HELIX-18] Moving some rebalancing methods to HelixAdmin from clustersetup
Date Thu, 03 Jan 2013 06:43:02 GMT
http://git-wip-us.apache.org/repos/asf/incubator-helix/blob/80e9c4a9/helix-core/src/main/java/org/apache/helix/tools/IdealStateCalculatorForStorageNode.java
----------------------------------------------------------------------
diff --git a/helix-core/src/main/java/org/apache/helix/tools/IdealStateCalculatorForStorageNode.java b/helix-core/src/main/java/org/apache/helix/tools/IdealStateCalculatorForStorageNode.java
deleted file mode 100644
index b9b1b7a..0000000
--- a/helix-core/src/main/java/org/apache/helix/tools/IdealStateCalculatorForStorageNode.java
+++ /dev/null
@@ -1,792 +0,0 @@
-package org.apache.helix.tools;
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import java.util.Random;
-import java.util.TreeMap;
-
-import org.apache.helix.HelixException;
-import org.apache.helix.ZNRecord;
-import org.apache.helix.model.IdealState.IdealStateProperty;
-
-
-/**
- * IdealStateCalculatorForStorageNode tries to optimally allocate master/slave partitions among
- * espresso storage nodes.
- *
- * Given a batch of storage nodes, the partition and replication factor, the algorithm first given a initial state
- * When new batches of storage nodes are added, the algorithm will calculate the new ideal state such that the total
- * partition movements are minimized.
- *
- */
-public class IdealStateCalculatorForStorageNode
-{
-  static final String _MasterAssignmentMap = "MasterAssignmentMap";
-  static final String _SlaveAssignmentMap = "SlaveAssignmentMap";
-  static final String _partitions = "partitions";
-  static final String _replicas = "replicas";
-
-  /**
-   * Calculate the initial ideal state given a batch of storage instances, the replication factor and
-   * number of partitions
-   *
-   * 1. Calculate the master assignment by random shuffling
-   * 2. for each storage instance, calculate the 1st slave assignment map, by another random shuffling
-   * 3. for each storage instance, calculate the i-th slave assignment map
-   * 4. Combine the i-th slave assignment maps together
-   *
-   * @param instanceNames
-   *          list of storage node instances
-   * @param partitions
-   *          number of partitions
-   * @param replicas
-   *          The number of replicas (slave partitions) per master partition
-   * @param masterStateValue
-   *          master state value: e.g. "MASTER" or "LEADER"
-   * @param slaveStateValue
-   *          slave state value: e.g. "SLAVE" or "STANDBY"
-   * @param resourceName
-   * @return a ZNRecord that contain the idealstate info
-   */
-  public static ZNRecord calculateIdealState(List<String> instanceNames, int partitions, int replicas, String resourceName,
-                                             String masterStateValue, String slaveStateValue)
-  {
-    Collections.sort(instanceNames);
-    if(instanceNames.size() < replicas + 1)
-    {
-      throw new HelixException("Number of instances must not be less than replicas + 1. "
-                                      + "instanceNr:" + instanceNames.size()
-                                      + ", replicas:" + replicas);
-    }
-    else if(partitions < instanceNames.size())
-    {
-      ZNRecord idealState = IdealStateCalculatorByShuffling.calculateIdealState(instanceNames, partitions, replicas, resourceName, 12345, masterStateValue, slaveStateValue);
-      int i = 0;
-      for(String partitionId : idealState.getMapFields().keySet())
-      {
-        Map<String, String> partitionAssignmentMap = idealState.getMapField(partitionId);
-        List<String> partitionAssignmentPriorityList = new ArrayList<String>();
-        String masterInstance = "";
-        for(String instanceName : partitionAssignmentMap.keySet())
-        {
-          if(partitionAssignmentMap.get(instanceName).equalsIgnoreCase(masterStateValue)
-              && masterInstance.equals(""))
-          {
-            masterInstance = instanceName;
-          }
-          else
-          {
-            partitionAssignmentPriorityList.add(instanceName);
-          }
-        }
-        Collections.shuffle(partitionAssignmentPriorityList, new Random(i++));
-        partitionAssignmentPriorityList.add(0, masterInstance);
-        idealState.setListField(partitionId, partitionAssignmentPriorityList);
-      }
-      return idealState;
-    }
-
-    Map<String, Object> result = calculateInitialIdealState(instanceNames, partitions, replicas);
-
-    return convertToZNRecord(result, resourceName, masterStateValue, slaveStateValue);
-  }
-
-  public static ZNRecord calculateIdealStateBatch(List<List<String>> instanceBatches, int partitions, int replicas, String resourceName,
-                                                  String masterStateValue, String slaveStateValue)
-  {
-    Map<String, Object> result = calculateInitialIdealState(instanceBatches.get(0), partitions, replicas);
-
-    for(int i = 1; i < instanceBatches.size(); i++)
-    {
-      result = calculateNextIdealState(instanceBatches.get(i), result);
-    }
-
-    return convertToZNRecord(result, resourceName, masterStateValue, slaveStateValue);
-  }
-
-  /**
-   * Convert the internal result (stored as a Map<String, Object>) into ZNRecord.
-   */
-  public static ZNRecord convertToZNRecord(Map<String, Object> result, String resourceName,
-                                    String masterStateValue, String slaveStateValue)
-  {
-    Map<String, List<Integer>> nodeMasterAssignmentMap
-    = (Map<String, List<Integer>>) (result.get(_MasterAssignmentMap));
-    Map<String, Map<String, List<Integer>>> nodeSlaveAssignmentMap
-        = (Map<String, Map<String, List<Integer>>>)(result.get(_SlaveAssignmentMap));
-
-    int partitions = (Integer)(result.get("partitions"));
-
-    ZNRecord idealState = new ZNRecord(resourceName);
-    idealState.setSimpleField(IdealStateProperty.NUM_PARTITIONS.toString(), String.valueOf(partitions));
-
-
-    for(String instanceName : nodeMasterAssignmentMap.keySet())
-    {
-      for(Integer partitionId : nodeMasterAssignmentMap.get(instanceName))
-      {
-        String partitionName = resourceName+"_"+partitionId;
-        if(!idealState.getMapFields().containsKey(partitionName))
-        {
-          idealState.setMapField(partitionName, new TreeMap<String, String>());
-        }
-        idealState.getMapField(partitionName).put(instanceName, masterStateValue);
-      }
-    }
-
-    for(String instanceName : nodeSlaveAssignmentMap.keySet())
-    {
-      Map<String, List<Integer>> slaveAssignmentMap = nodeSlaveAssignmentMap.get(instanceName);
-
-      for(String slaveNode: slaveAssignmentMap.keySet())
-      {
-        List<Integer> slaveAssignment = slaveAssignmentMap.get(slaveNode);
-        for(Integer partitionId: slaveAssignment)
-        {
-          String partitionName = resourceName+"_"+partitionId;
-          idealState.getMapField(partitionName).put(slaveNode, slaveStateValue);
-        }
-      }
-    }
-    // generate the priority list of instances per partition. Master should be at front and slave follows.
-
-    for(String partitionId : idealState.getMapFields().keySet())
-    {
-      Map<String, String> partitionAssignmentMap = idealState.getMapField(partitionId);
-      List<String> partitionAssignmentPriorityList = new ArrayList<String>();
-      String masterInstance = "";
-      for(String instanceName : partitionAssignmentMap.keySet())
-      {
-        if(partitionAssignmentMap.get(instanceName).equalsIgnoreCase(masterStateValue)
-            && masterInstance.equals(""))
-        {
-          masterInstance = instanceName;
-        }
-        else
-        {
-          partitionAssignmentPriorityList.add(instanceName);
-        }
-      }
-      Collections.shuffle(partitionAssignmentPriorityList);
-      partitionAssignmentPriorityList.add(0, masterInstance);
-      idealState.setListField(partitionId, partitionAssignmentPriorityList);
-    }
-    assert(result.containsKey("replicas"));
-    idealState.setSimpleField(IdealStateProperty.REPLICAS.toString(), result.get("replicas").toString());
-    return idealState;
-  }
-  /**
-   * Calculate the initial ideal state given a batch of storage instances, the replication factor and
-   * number of partitions
-   *
-   * 1. Calculate the master assignment by random shuffling
-   * 2. for each storage instance, calculate the 1st slave assignment map, by another random shuffling
-   * 3. for each storage instance, calculate the i-th slave assignment map
-   * 4. Combine the i-th slave assignment maps together
-   *
-   * @param instanceNames
-   *          list of storage node instances
-   * @param weight
-   *          weight for the initial storage node (each node has the same weight)
-   * @param partitions
-   *          number of partitions
-   * @param replicas
-   *          The number of replicas (slave partitions) per master partition
-   * @return a map that contain the idealstate info
-   */
-  public static Map<String, Object> calculateInitialIdealState(List<String> instanceNames, int partitions, int replicas)
-  {
-    Random r = new Random(54321);
-    assert(replicas <= instanceNames.size() - 1);
-
-    ArrayList<Integer> masterPartitionAssignment = new ArrayList<Integer>();
-    for(int i = 0;i< partitions; i++)
-    {
-      masterPartitionAssignment.add(i);
-    }
-    // shuffle the partition id array
-    Collections.shuffle(masterPartitionAssignment, new Random(r.nextInt()));
-
-    // 1. Generate the random master partition assignment
-    //    instanceName -> List of master partitions on that instance
-    Map<String, List<Integer>> nodeMasterAssignmentMap = new TreeMap<String, List<Integer>>();
-    for(int i = 0; i < masterPartitionAssignment.size(); i++)
-    {
-      String instanceName = instanceNames.get(i % instanceNames.size());
-      if(!nodeMasterAssignmentMap.containsKey(instanceName))
-      {
-        nodeMasterAssignmentMap.put(instanceName, new ArrayList<Integer>());
-      }
-      nodeMasterAssignmentMap.get(instanceName).add(masterPartitionAssignment.get(i));
-    }
-
-    // instanceName -> slave assignment for its master partitions
-    // slave assignment: instanceName -> list of slave partitions on it
-    List<Map<String, Map<String, List<Integer>>>> nodeSlaveAssignmentMapsList = new ArrayList<Map<String, Map<String, List<Integer>>>>(replicas);
-
-    Map<String, Map<String, List<Integer>>> firstNodeSlaveAssignmentMap = new TreeMap<String, Map<String, List<Integer>>>();
-    Map<String, Map<String, List<Integer>>> combinedNodeSlaveAssignmentMap = new TreeMap<String, Map<String, List<Integer>>>();
-
-    if(replicas > 0)
-    {
-      // 2. For each node, calculate the evenly distributed slave as the first slave assignment
-      // We will figure out the 2nd ...replicas-th slave assignment based on the first level slave assignment
-      for(int i = 0; i < instanceNames.size(); i++)
-      {
-        List<String> slaveInstances = new ArrayList<String>();
-        ArrayList<Integer> slaveAssignment = new ArrayList<Integer>();
-        TreeMap<String, List<Integer>> slaveAssignmentMap = new TreeMap<String, List<Integer>>();
-
-        for(int j = 0;j < instanceNames.size(); j++)
-        {
-          if(j != i)
-          {
-            slaveInstances.add(instanceNames.get(j));
-            slaveAssignmentMap.put(instanceNames.get(j), new ArrayList<Integer>());
-          }
-        }
-        // Get the number of master partitions on instanceName
-        List<Integer> masterAssignment =  nodeMasterAssignmentMap.get(instanceNames.get(i));
-        // do a random shuffling as in step 1, so that the first-level slave are distributed among rest instances
-
-
-        for(int j = 0;j < masterAssignment.size(); j++)
-        {
-          slaveAssignment.add(j);
-        }
-        Collections.shuffle(slaveAssignment, new Random(r.nextInt()));
-
-        Collections.shuffle(slaveInstances, new Random(instanceNames.get(i).hashCode()));
-
-        // Get the slave assignment map of node instanceName
-        for(int j = 0;j < masterAssignment.size(); j++)
-        {
-          String slaveInstanceName = slaveInstances.get(slaveAssignment.get(j) % slaveInstances.size());
-          if(!slaveAssignmentMap.containsKey(slaveInstanceName))
-          {
-            slaveAssignmentMap.put(slaveInstanceName, new ArrayList<Integer>());
-          }
-          slaveAssignmentMap.get(slaveInstanceName).add(masterAssignment.get(j));
-        }
-        firstNodeSlaveAssignmentMap.put(instanceNames.get(i), slaveAssignmentMap);
-      }
-      nodeSlaveAssignmentMapsList.add(firstNodeSlaveAssignmentMap);
-      // From the first slave assignment map, calculate the rest slave assignment maps
-      for(int replicaOrder = 1; replicaOrder < replicas; replicaOrder++)
-      {
-        // calculate the next slave partition assignment map
-        Map<String, Map<String, List<Integer>>> nextNodeSlaveAssignmentMap
-          = calculateNextSlaveAssignemntMap(firstNodeSlaveAssignmentMap, replicaOrder);
-        nodeSlaveAssignmentMapsList.add(nextNodeSlaveAssignmentMap);
-      }
-
-      // Combine the calculated 1...replicas-th slave assignment map together
-
-      for(String instanceName : nodeMasterAssignmentMap.keySet())
-      {
-        Map<String, List<Integer>> combinedSlaveAssignmentMap =  new TreeMap<String, List<Integer>>();
-
-        for(Map<String, Map<String, List<Integer>>> slaveNodeAssignmentMap : nodeSlaveAssignmentMapsList)
-        {
-          Map<String, List<Integer>> slaveAssignmentMap = slaveNodeAssignmentMap.get(instanceName);
-
-          for(String slaveInstance : slaveAssignmentMap.keySet())
-          {
-            if(!combinedSlaveAssignmentMap.containsKey(slaveInstance))
-            {
-              combinedSlaveAssignmentMap.put(slaveInstance, new ArrayList<Integer>());
-            }
-            combinedSlaveAssignmentMap.get(slaveInstance).addAll(slaveAssignmentMap.get(slaveInstance));
-          }
-        }
-        migrateSlaveAssignMapToNewInstances(combinedSlaveAssignmentMap, new ArrayList<String>());
-        combinedNodeSlaveAssignmentMap.put(instanceName, combinedSlaveAssignmentMap);
-      }
-    }
-    /*
-    // Print the result master and slave assignment maps
-    System.out.println("Master assignment:");
-    for(String instanceName : nodeMasterAssignmentMap.keySet())
-    {
-      System.out.println(instanceName+":");
-      for(Integer x : nodeMasterAssignmentMap.get(instanceName))
-      {
-        System.out.print(x+" ");
-      }
-      System.out.println();
-      System.out.println("Slave assignment:");
-
-      int slaveOrder = 1;
-      for(Map<String, Map<String, List<Integer>>> slaveNodeAssignmentMap : nodeSlaveAssignmentMapsList)
-      {
-        System.out.println("Slave assignment order :" + (slaveOrder++));
-        Map<String, List<Integer>> slaveAssignmentMap = slaveNodeAssignmentMap.get(instanceName);
-        for(String slaveName : slaveAssignmentMap.keySet())
-        {
-          System.out.print("\t" + slaveName +":\n\t" );
-          for(Integer x : slaveAssignmentMap.get(slaveName))
-          {
-            System.out.print(x + " ");
-          }
-          System.out.println("\n");
-        }
-      }
-      System.out.println("\nCombined slave assignment map");
-      Map<String, List<Integer>> slaveAssignmentMap = combinedNodeSlaveAssignmentMap.get(instanceName);
-      for(String slaveName : slaveAssignmentMap.keySet())
-      {
-        System.out.print("\t" + slaveName +":\n\t" );
-        for(Integer x : slaveAssignmentMap.get(slaveName))
-        {
-          System.out.print(x + " ");
-        }
-        System.out.println("\n");
-      }
-    }*/
-    Map<String, Object> result = new TreeMap<String, Object>();
-    result.put("MasterAssignmentMap", nodeMasterAssignmentMap);
-    result.put("SlaveAssignmentMap", combinedNodeSlaveAssignmentMap);
-    result.put("replicas", new Integer(replicas));
-    result.put("partitions", new Integer(partitions));
-    return result;
-  }
-  /**
-   * In the case there are more than 1 slave, we use the following algorithm to calculate the n-th slave
-   * assignment map based on the first level slave assignment map.
-   *
-   * @param firstInstanceSlaveAssignmentMap  the first slave assignment map for all instances
-   * @param order of the slave
-   * @return the n-th slave assignment map for all the instances
-   * */
-  static Map<String, Map<String, List<Integer>>> calculateNextSlaveAssignemntMap(Map<String, Map<String, List<Integer>>> firstInstanceSlaveAssignmentMap, int replicaOrder)
-  {
-    Map<String, Map<String, List<Integer>>> result = new TreeMap<String, Map<String, List<Integer>>>();
-
-    for(String currentInstance : firstInstanceSlaveAssignmentMap.keySet())
-    {
-      Map<String, List<Integer>> resultAssignmentMap = new TreeMap<String, List<Integer>>();
-      result.put(currentInstance, resultAssignmentMap);
-    }
-
-    for(String currentInstance : firstInstanceSlaveAssignmentMap.keySet())
-    {
-      Map<String, List<Integer>> previousSlaveAssignmentMap = firstInstanceSlaveAssignmentMap.get(currentInstance);
-      Map<String, List<Integer>> resultAssignmentMap = result.get(currentInstance);
-      int offset = replicaOrder - 1;
-      for(String instance : previousSlaveAssignmentMap.keySet())
-      {
-        List<String> otherInstances = new ArrayList<String>(previousSlaveAssignmentMap.size() - 1);
-        // Obtain an array of other instances
-        for(String otherInstance : previousSlaveAssignmentMap.keySet())
-        {
-          otherInstances.add(otherInstance);
-        }
-        Collections.sort(otherInstances);
-        int instanceIndex = -1;
-        for(int index = 0;index < otherInstances.size(); index++)
-        {
-          if(otherInstances.get(index).equalsIgnoreCase(instance))
-          {
-            instanceIndex = index;
-          }
-        }
-        assert(instanceIndex >= 0);
-        if(instanceIndex == otherInstances.size() - 1)
-        {
-          instanceIndex --;
-        }
-        // Since we need to evenly distribute the slaves on "instance" to other partitions, we
-        // need to remove "instance" from the array.
-        otherInstances.remove(instance);
-
-        // distribute previous slave assignment to other instances.
-        List<Integer> previousAssignmentList = previousSlaveAssignmentMap.get(instance);
-        for(int i = 0; i < previousAssignmentList.size(); i++)
-        {
-
-          // Evenly distribute the previousAssignmentList to the remaining other instances
-          int newInstanceIndex = (i + offset + instanceIndex) % otherInstances.size();
-          String newInstance = otherInstances.get(newInstanceIndex);
-          if(!resultAssignmentMap.containsKey(newInstance))
-          {
-            resultAssignmentMap.put(newInstance, new ArrayList<Integer>());
-          }
-          resultAssignmentMap.get(newInstance).add(previousAssignmentList.get(i));
-        }
-      }
-    }
-    return result;
-  }
-
-  /**
-   * Given the current idealState, and the list of new Instances needed to be added, calculate the
-   * new Ideal state.
-   *
-   * 1. Calculate how many master partitions should be moved to the new cluster of instances
-   * 2. assign the number of master partitions px to be moved to each previous node
-   * 3. for each previous node,
-   *    3.1 randomly choose px nodes, move them to temp list
-   *    3.2 for each px nodes, remove them from the slave assignment map; record the map position of
-   *        the partition;
-   *    3.3 calculate # of new nodes that should be put in the slave assignment map
-   *    3.4 even-fy the slave assignment map;
-   *    3.5 randomly place # of new nodes that should be placed in
-   *
-   * 4. from all the temp master node list get from 3.1,
-   *    4.1 randomly assign them to nodes in the new cluster
-   *
-   * 5. for each node in the new cluster,
-   *    5.1 assemble the slave assignment map
-   *    5.2 even-fy the slave assignment map
-   *
-   * @param newInstances
-   *          list of new added storage node instances
-   * @param weight
-   *          weight for the new storage nodes (each node has the same weight)
-   * @param previousIdealState
-   *          The previous ideal state
-   * @return a map that contain the updated idealstate info
-   * */
-  public static Map<String, Object> calculateNextIdealState(List<String> newInstances, Map<String, Object> previousIdealState)
-  {
-    // Obtain the master / slave assignment info maps
-    Collections.sort(newInstances);
-    Map<String, List<Integer>> previousMasterAssignmentMap
-        = (Map<String, List<Integer>>) (previousIdealState.get("MasterAssignmentMap"));
-    Map<String, Map<String, List<Integer>>> nodeSlaveAssignmentMap
-        = (Map<String, Map<String, List<Integer>>>)(previousIdealState.get("SlaveAssignmentMap"));
-
-    List<String> oldInstances = new ArrayList<String>();
-    for(String oldInstance : previousMasterAssignmentMap.keySet())
-    {
-      oldInstances.add(oldInstance);
-    }
-
-    int previousInstanceNum = previousMasterAssignmentMap.size();
-    int partitions = (Integer)(previousIdealState.get("partitions"));
-
-    // TODO: take weight into account when calculate this
-
-    int totalMasterParitionsToMove
-        = partitions * (newInstances.size()) / (previousInstanceNum + newInstances.size());
-    int numMastersFromEachNode = totalMasterParitionsToMove / previousInstanceNum;
-    int remain = totalMasterParitionsToMove % previousInstanceNum;
-
-    // Note that when remain > 0, we should make [remain] moves with (numMastersFromEachNode + 1) partitions.
-    // And we should first choose those (numMastersFromEachNode + 1) moves from the instances that has more
-    // master partitions
-    List<Integer> masterPartitionListToMove = new ArrayList<Integer>();
-
-    // For corresponding moved slave partitions, keep track of their original location; the new node does not
-    // need to migrate all of them.
-    Map<String, List<Integer>> slavePartitionsToMoveMap = new TreeMap<String, List<Integer>>();
-
-    // Make sure that the instances that holds more master partitions are put in front
-    List<String> bigList = new ArrayList<String>(), smallList = new ArrayList<String>();
-    for(String oldInstance : previousMasterAssignmentMap.keySet())
-    {
-      List<Integer> masterAssignmentList = previousMasterAssignmentMap.get(oldInstance);
-      if(masterAssignmentList.size() > numMastersFromEachNode)
-      {
-        bigList.add(oldInstance);
-      }
-      else
-      {
-        smallList.add(oldInstance);
-      }
-    }
-    // "sort" the list, such that the nodes that has more master partitions moves more partitions to the
-    // new added batch of instances.
-    bigList.addAll(smallList);
-    int totalSlaveMoves = 0;
-    for(String oldInstance : bigList)
-    {
-      List<Integer> masterAssignmentList = previousMasterAssignmentMap.get(oldInstance);
-      int numToChoose = numMastersFromEachNode;
-      if(remain > 0)
-      {
-        numToChoose = numMastersFromEachNode + 1;
-        remain --;
-      }
-      // randomly remove numToChoose of master partitions to the new added nodes
-      ArrayList<Integer> masterPartionsMoved = new ArrayList<Integer>();
-      randomSelect(masterAssignmentList, masterPartionsMoved, numToChoose);
-
-      masterPartitionListToMove.addAll(masterPartionsMoved);
-      Map<String, List<Integer>> slaveAssignmentMap = nodeSlaveAssignmentMap.get(oldInstance);
-      removeFromSlaveAssignmentMap(slaveAssignmentMap, masterPartionsMoved, slavePartitionsToMoveMap);
-
-      // Make sure that for old instances, the slave placement map is evenly distributed
-      // Trace the "local slave moves", which should together contribute to most of the slave migrations
-      int movesWithinInstance = migrateSlaveAssignMapToNewInstances(slaveAssignmentMap, newInstances);
-      // System.out.println("local moves: "+ movesWithinInstance);
-      totalSlaveMoves += movesWithinInstance;
-    }
-    // System.out.println("local slave moves total: "+ totalSlaveMoves);
-    // calculate the master /slave assignment for the new added nodes
-
-    // We already have the list of master partitions that will migrate to new batch of instances,
-    // shuffle the partitions and assign them to new instances
-    Collections.shuffle(masterPartitionListToMove, new Random(12345));
-    for(int i = 0;i < newInstances.size(); i++)
-    {
-      String newInstance = newInstances.get(i);
-      List<Integer> masterPartitionList = new ArrayList<Integer>();
-      for(int j = 0;j < masterPartitionListToMove.size(); j++)
-      {
-        if(j % newInstances.size() == i)
-        {
-          masterPartitionList.add(masterPartitionListToMove.get(j));
-        }
-      }
-
-      Map<String, List<Integer>> slavePartitionMap = new TreeMap<String, List<Integer>>();
-      for(String oldInstance : oldInstances)
-      {
-        slavePartitionMap.put(oldInstance, new ArrayList<Integer>());
-      }
-      // Build the slave assignment map for the new instance, based on the saved information
-      // about those slave partition locations in slavePartitionsToMoveMap
-      for(Integer x : masterPartitionList)
-      {
-        for(String oldInstance : slavePartitionsToMoveMap.keySet())
-        {
-          List<Integer> slaves = slavePartitionsToMoveMap.get(oldInstance);
-          if(slaves.contains(x))
-          {
-            slavePartitionMap.get(oldInstance).add(x);
-          }
-        }
-      }
-      // add entry for other new instances into the slavePartitionMap
-      List<String> otherNewInstances = new ArrayList<String>();
-      for(String instance : newInstances)
-      {
-        if(!instance.equalsIgnoreCase(newInstance))
-        {
-          otherNewInstances.add(instance);
-        }
-      }
-      // Make sure that slave partitions are evenly distributed
-      migrateSlaveAssignMapToNewInstances(slavePartitionMap, otherNewInstances);
-
-      // Update the result in the result map. We can reuse the input previousIdealState map as
-      // the result.
-      previousMasterAssignmentMap.put(newInstance, masterPartitionList);
-      nodeSlaveAssignmentMap.put(newInstance, slavePartitionMap);
-
-    }
-    /*
-    // Print content of the master/ slave assignment maps
-    for(String instanceName : previousMasterAssignmentMap.keySet())
-    {
-      System.out.println(instanceName+":");
-      for(Integer x : previousMasterAssignmentMap.get(instanceName))
-      {
-        System.out.print(x+" ");
-      }
-      System.out.println("\nmaster partition moved:");
-
-      System.out.println();
-      System.out.println("Slave assignment:");
-
-      Map<String, List<Integer>> slaveAssignmentMap = nodeSlaveAssignmentMap.get(instanceName);
-      for(String slaveName : slaveAssignmentMap.keySet())
-      {
-        System.out.print("\t" + slaveName +":\n\t" );
-        for(Integer x : slaveAssignmentMap.get(slaveName))
-        {
-          System.out.print(x + " ");
-        }
-        System.out.println("\n");
-      }
-    }
-
-    System.out.println("Master partitions migrated to new instances");
-    for(Integer x : masterPartitionListToMove)
-    {
-        System.out.print(x+" ");
-    }
-    System.out.println();
-
-    System.out.println("Slave partitions migrated to new instances");
-    for(String oldInstance : slavePartitionsToMoveMap.keySet())
-    {
-        System.out.print(oldInstance + ": ");
-        for(Integer x : slavePartitionsToMoveMap.get(oldInstance))
-        {
-          System.out.print(x+" ");
-        }
-        System.out.println();
-    }
-    */
-    return previousIdealState;
-  }
-  
-  public ZNRecord calculateNextIdealState(List<String> newInstances, Map<String, Object> previousIdealState,
-       String resourceName, String masterStateValue, String slaveStateValue)
-  {
-    return convertToZNRecord(calculateNextIdealState(newInstances, previousIdealState), resourceName, masterStateValue, slaveStateValue);
-  }
-  /**
-   * Given the list of master partition that will be migrated away from the storage instance,
-   * Remove their entries from the local instance slave assignment map.
-   *
-   * @param slaveAssignmentMap  the local instance slave assignment map
-   * @param masterPartionsMoved the list of master partition ids that will be migrated away
-   * @param removedAssignmentMap keep track of the removed slave assignment info. The info can be
-   *        used by new added storage nodes.
-   * */
-  static void removeFromSlaveAssignmentMap( Map<String, List<Integer>>slaveAssignmentMap, List<Integer> masterPartionsMoved, Map<String, List<Integer>> removedAssignmentMap)
-  {
-    for(String instanceName : slaveAssignmentMap.keySet())
-    {
-      List<Integer> slaveAssignment = slaveAssignmentMap.get(instanceName);
-      for(Integer partitionId: masterPartionsMoved)
-      {
-        if(slaveAssignment.contains(partitionId))
-        {
-          slaveAssignment.remove(partitionId);
-          if(!removedAssignmentMap.containsKey(instanceName))
-          {
-            removedAssignmentMap.put(instanceName, new ArrayList<Integer>());
-          }
-          removedAssignmentMap.get(instanceName).add(partitionId);
-        }
-      }
-    }
-  }
-
-  /**
-   * Since some new storage instances are added, each existing storage instance should migrate some
-   * slave partitions to the new added instances.
-   *
-   * The algorithm keeps moving one partition to from the instance that hosts most slave partitions
-   * to the instance that hosts least number of partitions, until max-min <= 1.
-   *
-   * In this way we can guarantee that all instances hosts almost same number of slave partitions, also
-   * slave partitions are evenly distributed.
-   *
-   * @param slaveAssignmentMap  the local instance slave assignment map
-   * @param masterPartionsMoved the list of master partition ids that will be migrated away
-   * @param removedAssignmentMap keep track of the removed slave assignment info. The info can be
-   *        used by new added storage nodes.
-   * */
-  static int migrateSlaveAssignMapToNewInstances(Map<String, List<Integer>> nodeSlaveAssignmentMap, List<String> newInstances)
-  {
-    int moves = 0;
-    boolean done = false;
-    for(String newInstance : newInstances)
-    {
-      nodeSlaveAssignmentMap.put(newInstance, new ArrayList<Integer>());
-    }
-    while(!done)
-    {
-      List<Integer> maxAssignment = null, minAssignment = null;
-      int minCount = Integer.MAX_VALUE, maxCount = Integer.MIN_VALUE;
-      String minInstance = "";
-      for(String instanceName : nodeSlaveAssignmentMap.keySet())
-      {
-        List<Integer> slaveAssignment = nodeSlaveAssignmentMap.get(instanceName);
-        if(minCount > slaveAssignment.size())
-        {
-          minCount = slaveAssignment.size();
-          minAssignment = slaveAssignment;
-          minInstance = instanceName;
-        }
-        if(maxCount < slaveAssignment.size())
-        {
-          maxCount = slaveAssignment.size();
-          maxAssignment = slaveAssignment;
-        }
-      }
-      if(maxCount - minCount <= 1 )
-      {
-        done = true;
-      }
-      else
-      {
-        int indexToMove = -1;
-        // find a partition that is not contained in the minAssignment list
-        for(int i = 0; i < maxAssignment.size(); i++ )
-        {
-          if(!minAssignment.contains(maxAssignment.get(i)))
-          {
-            indexToMove = i;
-            break;
-          }
-        }
-
-        minAssignment.add(maxAssignment.get(indexToMove));
-        maxAssignment.remove(indexToMove);
-
-        if(newInstances.contains(minInstance))
-        {
-          moves++;
-        }
-      }
-    }
-    return moves;
-  }
-
-  /**
-   * Randomly select a number of elements from original list and put them in the selectedList
-   * The algorithm is used to select master partitions to be migrated when new instances are added.
-   *
-   *
-   * @param originalList  the original list
-   * @param selectedList  the list that contain selected elements
-   * @param num number of elements to be selected
-   * */
-  static void randomSelect(List<Integer> originalList, List<Integer> selectedList, int num)
-  {
-    assert(originalList.size() >= num);
-    int[] indexArray = new int[originalList.size()];
-    for(int i = 0;i < indexArray.length; i++)
-    {
-      indexArray[i] = i;
-    }
-    int numRemains = originalList.size();
-    Random r = new Random(numRemains);
-    for(int j = 0;j < num; j++)
-    {
-      int randIndex = r.nextInt(numRemains);
-      selectedList.add(originalList.get(randIndex));
-      originalList.remove(randIndex);
-      numRemains --;
-    }
-  }
-
-  public static void main(String args[])
-  {
-    List<String> instanceNames = new ArrayList<String>();
-    for(int i = 0;i < 10; i++)
-    {
-      instanceNames.add("localhost:123" + i);
-    }
-    int partitions = 48*3, replicas = 3;
-    Map<String, Object> resultOriginal = IdealStateCalculatorForStorageNode.calculateInitialIdealState(instanceNames, partitions, replicas);
-
-  }
-}

http://git-wip-us.apache.org/repos/asf/incubator-helix/blob/80e9c4a9/helix-core/src/main/java/org/apache/helix/util/RebalanceUtil.java
----------------------------------------------------------------------
diff --git a/helix-core/src/main/java/org/apache/helix/util/RebalanceUtil.java b/helix-core/src/main/java/org/apache/helix/util/RebalanceUtil.java
new file mode 100644
index 0000000..f6b02e8
--- /dev/null
+++ b/helix-core/src/main/java/org/apache/helix/util/RebalanceUtil.java
@@ -0,0 +1,146 @@
+package org.apache.helix.util;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.TreeMap;
+
+import org.apache.helix.HelixException;
+import org.apache.helix.model.IdealState;
+import org.apache.helix.model.StateModelDefinition;
+
+public class RebalanceUtil
+{
+  public static Map<String, Object> buildInternalIdealState(IdealState state)
+  {
+    // Try parse the partition number from name DB_n. If not, sort the partitions and
+    // assign id
+    Map<String, Integer> partitionIndex = new HashMap<String, Integer>();
+    Map<String, String> reversePartitionIndex = new HashMap<String, String>();
+    boolean indexInPartitionName = true;
+    for (String partitionId : state.getPartitionSet())
+    {
+      int lastPos = partitionId.lastIndexOf("_");
+      if (lastPos < 0)
+      {
+        indexInPartitionName = false;
+        break;
+      }
+      try
+      {
+        String idStr = partitionId.substring(lastPos + 1);
+        int partition = Integer.parseInt(idStr);
+        partitionIndex.put(partitionId, partition);
+        reversePartitionIndex.put(state.getResourceName() + "_" + partition, partitionId);
+      }
+      catch (Exception e)
+      {
+        indexInPartitionName = false;
+        partitionIndex.clear();
+        reversePartitionIndex.clear();
+        break;
+      }
+    }
+
+    if (indexInPartitionName == false)
+    {
+      List<String> partitions = new ArrayList<String>();
+      partitions.addAll(state.getPartitionSet());
+      Collections.sort(partitions);
+      for (int i = 0; i < partitions.size(); i++)
+      {
+        partitionIndex.put(partitions.get(i), i);
+        reversePartitionIndex.put(state.getResourceName() + "_" + i, partitions.get(i));
+      }
+    }
+
+    Map<String, List<Integer>> nodeMasterAssignmentMap =
+        new TreeMap<String, List<Integer>>();
+    Map<String, Map<String, List<Integer>>> combinedNodeSlaveAssignmentMap =
+        new TreeMap<String, Map<String, List<Integer>>>();
+    for (String partition : state.getPartitionSet())
+    {
+      List<String> instances = state.getRecord().getListField(partition);
+      String master = instances.get(0);
+      if (!nodeMasterAssignmentMap.containsKey(master))
+      {
+        nodeMasterAssignmentMap.put(master, new ArrayList<Integer>());
+      }
+      if (!combinedNodeSlaveAssignmentMap.containsKey(master))
+      {
+        combinedNodeSlaveAssignmentMap.put(master, new TreeMap<String, List<Integer>>());
+      }
+      nodeMasterAssignmentMap.get(master).add(partitionIndex.get(partition));
+      for (int i = 1; i < instances.size(); i++)
+      {
+        String instance = instances.get(i);
+        Map<String, List<Integer>> slaveMap = combinedNodeSlaveAssignmentMap.get(master);
+        if (!slaveMap.containsKey(instance))
+        {
+          slaveMap.put(instance, new ArrayList<Integer>());
+        }
+        slaveMap.get(instance).add(partitionIndex.get(partition));
+      }
+    }
+
+    Map<String, Object> result = new TreeMap<String, Object>();
+    result.put("MasterAssignmentMap", nodeMasterAssignmentMap);
+    result.put("SlaveAssignmentMap", combinedNodeSlaveAssignmentMap);
+    result.put("replicas", Integer.parseInt(state.getReplicas()));
+    result.put("partitions", new Integer(state.getRecord().getListFields().size()));
+    result.put("reversePartitionIndex", reversePartitionIndex);
+    return result;
+  }
+  public static String[] parseStates(String clusterName, StateModelDefinition stateModDef)
+  {
+    String[] result = new String[2];
+    String masterStateValue = null, slaveStateValue = null;
+
+    // StateModelDefinition def = new StateModelDefinition(stateModDef);
+
+    List<String> statePriorityList = stateModDef.getStatesPriorityList();
+
+    for (String state : statePriorityList)
+    {
+      String count = stateModDef.getNumInstancesPerState(state);
+      if (count.equals("1"))
+      {
+        if (masterStateValue != null)
+        {
+          throw new HelixException("Invalid or unsupported state model definition");
+        }
+        masterStateValue = state;
+      }
+      else if (count.equalsIgnoreCase("R"))
+      {
+        if (slaveStateValue != null)
+        {
+          throw new HelixException("Invalid or unsupported state model definition");
+        }
+        slaveStateValue = state;
+      }
+      else if (count.equalsIgnoreCase("N"))
+      {
+        if (!(masterStateValue == null && slaveStateValue == null))
+        {
+          throw new HelixException("Invalid or unsupported state model definition");
+        }
+        masterStateValue = slaveStateValue = state;
+      }
+    }
+    if (masterStateValue == null && slaveStateValue == null)
+    {
+      throw new HelixException("Invalid or unsupported state model definition");
+    }
+
+    if (masterStateValue == null)
+    {
+      masterStateValue = slaveStateValue;
+    }
+    result[0] = masterStateValue;
+    result[1] = slaveStateValue;
+    return result;
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-helix/blob/80e9c4a9/helix-core/src/test/java/org/apache/helix/TestEspressoStorageClusterIdealState.java
----------------------------------------------------------------------
diff --git a/helix-core/src/test/java/org/apache/helix/TestEspressoStorageClusterIdealState.java b/helix-core/src/test/java/org/apache/helix/TestEspressoStorageClusterIdealState.java
index ef095d5..6634175 100644
--- a/helix-core/src/test/java/org/apache/helix/TestEspressoStorageClusterIdealState.java
+++ b/helix-core/src/test/java/org/apache/helix/TestEspressoStorageClusterIdealState.java
@@ -30,7 +30,8 @@ import java.util.TreeSet;
 import org.apache.helix.ZNRecord;
 import org.apache.helix.model.IdealState;
 import org.apache.helix.tools.ClusterSetup;
-import org.apache.helix.tools.IdealStateCalculatorForStorageNode;
+import org.apache.helix.tools.DefaultIdealStateCalculator;
+import org.apache.helix.util.RebalanceUtil;
 import org.testng.Assert;
 import org.testng.AssertJUnit;
 import org.testng.annotations.Test;
@@ -48,7 +49,7 @@ public class TestEspressoStorageClusterIdealState
       instanceNames.add("localhost:123" + i);
     }
     int partitions = 8, replicas = 0;
-    Map<String, Object> result0 = IdealStateCalculatorForStorageNode.calculateInitialIdealState(instanceNames, partitions, replicas);
+    Map<String, Object> result0 = DefaultIdealStateCalculator.calculateInitialIdealState(instanceNames, partitions, replicas);
     Verify(result0, partitions,replicas);
 
     partitions = 8192;
@@ -59,12 +60,12 @@ public class TestEspressoStorageClusterIdealState
     {
       instanceNames.add("localhost:123" + i);
     }
-    Map<String, Object> resultOriginal = IdealStateCalculatorForStorageNode.calculateInitialIdealState(instanceNames, partitions, replicas);
+    Map<String, Object> resultOriginal = DefaultIdealStateCalculator.calculateInitialIdealState(instanceNames, partitions, replicas);
 
     Verify(resultOriginal, partitions,replicas);
     printStat(resultOriginal);
 
-    Map<String, Object> result1 = IdealStateCalculatorForStorageNode.calculateInitialIdealState(instanceNames, partitions, replicas);
+    Map<String, Object> result1 = DefaultIdealStateCalculator.calculateInitialIdealState(instanceNames, partitions, replicas);
 
     List<String> instanceNames2 = new ArrayList<String>();
     for(int i = 30;i < 35; i++)
@@ -72,7 +73,7 @@ public class TestEspressoStorageClusterIdealState
       instanceNames2.add("localhost:123" + i);
     }
 
-    IdealStateCalculatorForStorageNode.calculateNextIdealState(instanceNames2, result1);
+    DefaultIdealStateCalculator.calculateNextIdealState(instanceNames2, result1);
 
     List<String> instanceNames3 = new ArrayList<String>();
     for(int i = 35;i < 40; i++)
@@ -80,7 +81,7 @@ public class TestEspressoStorageClusterIdealState
       instanceNames3.add("localhost:123" + i);
     }
 
-    IdealStateCalculatorForStorageNode.calculateNextIdealState(instanceNames3, result1);
+    DefaultIdealStateCalculator.calculateNextIdealState(instanceNames3, result1);
     Double masterKeepRatio = 0.0, slaveKeepRatio = 0.0;
     Verify(result1, partitions,replicas);
     double[] result = compareResult(resultOriginal, result1);
@@ -102,11 +103,11 @@ public class TestEspressoStorageClusterIdealState
       instanceNames.add("localhost:123" + i);
     }
     
-    Map<String, Object> resultOriginal = IdealStateCalculatorForStorageNode.calculateInitialIdealState(instanceNames, partitions, replicas);
+    Map<String, Object> resultOriginal = DefaultIdealStateCalculator.calculateInitialIdealState(instanceNames, partitions, replicas);
     
-    ZNRecord idealState1 = IdealStateCalculatorForStorageNode.convertToZNRecord(resultOriginal, "TestDB", "MASTER", "SLAVE");
+    ZNRecord idealState1 = DefaultIdealStateCalculator.convertToZNRecord(resultOriginal, "TestDB", "MASTER", "SLAVE");
     
-    Map<String, Object> result1 = ClusterSetup.buildInternalIdealState(new IdealState(idealState1));
+    Map<String, Object> result1 = RebalanceUtil.buildInternalIdealState(new IdealState(idealState1));
     
     List<String> instanceNames2 = new ArrayList<String>();
     for(int i = 30;i < 35; i++)
@@ -114,7 +115,7 @@ public class TestEspressoStorageClusterIdealState
       instanceNames2.add("localhost:123" + i);
     }
     
-    Map<String, Object> result2 = IdealStateCalculatorForStorageNode.calculateNextIdealState(instanceNames2, result1);
+    Map<String, Object> result2 = DefaultIdealStateCalculator.calculateNextIdealState(instanceNames2, result1);
     
     Verify(resultOriginal, partitions,replicas);
     Verify(result2, partitions,replicas);

http://git-wip-us.apache.org/repos/asf/incubator-helix/blob/80e9c4a9/helix-core/src/test/java/org/apache/helix/controller/stages/TestCompatibilityCheckStage.java
----------------------------------------------------------------------
diff --git a/helix-core/src/test/java/org/apache/helix/controller/stages/TestCompatibilityCheckStage.java b/helix-core/src/test/java/org/apache/helix/controller/stages/TestCompatibilityCheckStage.java
index 6b0545f..ecec60c 100644
--- a/helix-core/src/test/java/org/apache/helix/controller/stages/TestCompatibilityCheckStage.java
+++ b/helix-core/src/test/java/org/apache/helix/controller/stages/TestCompatibilityCheckStage.java
@@ -31,7 +31,7 @@ import org.apache.helix.controller.stages.ReadClusterDataStage;
 import org.apache.helix.model.IdealState;
 import org.apache.helix.model.LiveInstance;
 import org.apache.helix.model.LiveInstance.LiveInstanceProperty;
-import org.apache.helix.tools.IdealStateCalculatorForStorageNode;
+import org.apache.helix.tools.DefaultIdealStateCalculator;
 import org.testng.Assert;
 import org.testng.annotations.Test;
 
@@ -47,7 +47,7 @@ public class TestCompatibilityCheckStage extends BaseStageTest
 
     // set ideal state
     String resourceName = "testResource";
-    ZNRecord record = IdealStateCalculatorForStorageNode.calculateIdealState(
+    ZNRecord record = DefaultIdealStateCalculator.calculateIdealState(
         instances, partitions, replicas, resourceName, "MASTER", "SLAVE");
     IdealState idealState = new IdealState(record);
     idealState.setStateModelDefRef("MasterSlave");

http://git-wip-us.apache.org/repos/asf/incubator-helix/blob/80e9c4a9/helix-core/src/test/java/org/apache/helix/controller/stages/TestResourceComputationStage.java
----------------------------------------------------------------------
diff --git a/helix-core/src/test/java/org/apache/helix/controller/stages/TestResourceComputationStage.java b/helix-core/src/test/java/org/apache/helix/controller/stages/TestResourceComputationStage.java
index c5c4c45..c0b6528 100644
--- a/helix-core/src/test/java/org/apache/helix/controller/stages/TestResourceComputationStage.java
+++ b/helix-core/src/test/java/org/apache/helix/controller/stages/TestResourceComputationStage.java
@@ -36,7 +36,7 @@ import org.apache.helix.model.CurrentState;
 import org.apache.helix.model.IdealState;
 import org.apache.helix.model.LiveInstance;
 import org.apache.helix.model.Resource;
-import org.apache.helix.tools.IdealStateCalculatorForStorageNode;
+import org.apache.helix.tools.DefaultIdealStateCalculator;
 import org.testng.AssertJUnit;
 import org.testng.annotations.Test;
 
@@ -60,7 +60,7 @@ public class TestResourceComputationStage extends BaseStageTest
     int partitions = 10;
     int replicas = 1;
     String resourceName = "testResource";
-    ZNRecord record = IdealStateCalculatorForStorageNode.calculateIdealState(
+    ZNRecord record = DefaultIdealStateCalculator.calculateIdealState(
         instances, partitions, replicas, resourceName, "MASTER", "SLAVE");
     IdealState idealState = new IdealState(record);
     idealState.setStateModelDefRef("MasterSlave");
@@ -133,7 +133,7 @@ public class TestResourceComputationStage extends BaseStageTest
       int partitions = 10;
       int replicas = 1;
       String resourceName = resources[i];
-      ZNRecord record = IdealStateCalculatorForStorageNode
+      ZNRecord record = DefaultIdealStateCalculator
           .calculateIdealState(instances, partitions, replicas,
               resourceName, "MASTER", "SLAVE");
       IdealState idealState = new IdealState(record);

http://git-wip-us.apache.org/repos/asf/incubator-helix/blob/80e9c4a9/helix-core/src/test/java/org/apache/helix/integration/TestAutoIsWithEmptyMap.java
----------------------------------------------------------------------
diff --git a/helix-core/src/test/java/org/apache/helix/integration/TestAutoIsWithEmptyMap.java b/helix-core/src/test/java/org/apache/helix/integration/TestAutoIsWithEmptyMap.java
index 2d3bf42..d05a288 100644
--- a/helix-core/src/test/java/org/apache/helix/integration/TestAutoIsWithEmptyMap.java
+++ b/helix-core/src/test/java/org/apache/helix/integration/TestAutoIsWithEmptyMap.java
@@ -31,7 +31,7 @@ import org.apache.helix.controller.HelixControllerMain;
 import org.apache.helix.mock.participant.MockParticipant;
 import org.apache.helix.model.IdealState;
 import org.apache.helix.tools.ClusterStateVerifier;
-import org.apache.helix.tools.IdealStateCalculatorForStorageNode;
+import org.apache.helix.tools.DefaultIdealStateCalculator;
 import org.apache.helix.tools.ClusterStateVerifier.BestPossAndExtViewZkVerifier;
 import org.testng.Assert;
 import org.testng.annotations.Test;
@@ -66,7 +66,7 @@ public class TestAutoIsWithEmptyMap extends ZkIntegrationTestBase
       int port = 12918 + i;
       instanceNames.add("localhost_" + port);
     }
-    ZNRecord idealState = IdealStateCalculatorForStorageNode.calculateIdealState(instanceNames, 10,
+    ZNRecord idealState = DefaultIdealStateCalculator.calculateIdealState(instanceNames, 10,
         2, "TestDB0", "LEADER", "STANDBY");
     // System.out.println(idealState);
     // curIdealState.setSimpleField(IdealState.IdealStateProperty.IDEAL_STATE_MODE.toString(),

http://git-wip-us.apache.org/repos/asf/incubator-helix/blob/80e9c4a9/helix-core/src/test/java/org/apache/helix/integration/TestDriver.java
----------------------------------------------------------------------
diff --git a/helix-core/src/test/java/org/apache/helix/integration/TestDriver.java b/helix-core/src/test/java/org/apache/helix/integration/TestDriver.java
index 95ec9fe..5dd411f 100644
--- a/helix-core/src/test/java/org/apache/helix/integration/TestDriver.java
+++ b/helix-core/src/test/java/org/apache/helix/integration/TestDriver.java
@@ -43,7 +43,7 @@ import org.apache.helix.store.PropertyJsonSerializer;
 import org.apache.helix.store.PropertyStoreException;
 import org.apache.helix.tools.ClusterSetup;
 import org.apache.helix.tools.ClusterStateVerifier;
-import org.apache.helix.tools.IdealStateCalculatorForStorageNode;
+import org.apache.helix.tools.DefaultIdealStateCalculator;
 import org.apache.helix.tools.TestCommand;
 import org.apache.helix.tools.TestExecutor;
 import org.apache.helix.tools.TestTrigger;
@@ -364,7 +364,7 @@ public class TestDriver
     for (int i = 0; i < testInfo._numDb; i++)
     {
       String dbName = TEST_DB_PREFIX + i;
-      ZNRecord destIS = IdealStateCalculatorForStorageNode.calculateIdealState(instanceNames,
+      ZNRecord destIS = DefaultIdealStateCalculator.calculateIdealState(instanceNames,
           testInfo._numPartitionsPerDb, testInfo._replica - 1, dbName, "MASTER", "SLAVE");
       // destIS.setId(dbName);
       destIS.setSimpleField(IdealStateProperty.IDEAL_STATE_MODE.toString(),

http://git-wip-us.apache.org/repos/asf/incubator-helix/blob/80e9c4a9/helix-core/src/test/java/org/apache/helix/integration/TestExpandCluster.java
----------------------------------------------------------------------
diff --git a/helix-core/src/test/java/org/apache/helix/integration/TestExpandCluster.java b/helix-core/src/test/java/org/apache/helix/integration/TestExpandCluster.java
index bde3ce7..8356b54 100644
--- a/helix-core/src/test/java/org/apache/helix/integration/TestExpandCluster.java
+++ b/helix-core/src/test/java/org/apache/helix/integration/TestExpandCluster.java
@@ -24,6 +24,7 @@ import java.util.Map;
 import org.apache.helix.TestEspressoStorageClusterIdealState;
 import org.apache.helix.model.IdealState;
 import org.apache.helix.tools.ClusterSetup;
+import org.apache.helix.util.RebalanceUtil;
 import org.testng.Assert;
 import org.testng.annotations.Test;
 
@@ -59,8 +60,8 @@ public class TestExpandCluster extends ZkStandAloneCMTestBase
     IdealState testDB2_1 = _setupTool.getClusterManagementTool().getResourceIdealState(CLUSTER_NAME, DB2);
     IdealState testDB3_1 = _setupTool.getClusterManagementTool().getResourceIdealState(CLUSTER_NAME, DB3);
     
-    Map<String, Object> resultOld2 = ClusterSetup.buildInternalIdealState(testDB2);
-    Map<String, Object> result2 = ClusterSetup.buildInternalIdealState(testDB2_1);
+    Map<String, Object> resultOld2 = RebalanceUtil.buildInternalIdealState(testDB2);
+    Map<String, Object> result2 = RebalanceUtil.buildInternalIdealState(testDB2_1);
     
     TestEspressoStorageClusterIdealState.Verify(result2, partitions, replica - 1);
 
@@ -80,8 +81,8 @@ public class TestExpandCluster extends ZkStandAloneCMTestBase
     Assert.assertTrue(testDB3_1.getRecord().getMapFields().keySet().containsAll(testDB3.getRecord().getMapFields().keySet()));
     Assert.assertTrue(testDB3_1.getRecord().getMapFields().size() == testDB3.getRecord().getMapFields().size());
     
-    Map<String, Object> resultOld = ClusterSetup.buildInternalIdealState(testDB0);
-    Map<String, Object> resultNew = ClusterSetup.buildInternalIdealState(testDB0_1);
+    Map<String, Object> resultOld = RebalanceUtil.buildInternalIdealState(testDB0);
+    Map<String, Object> resultNew = RebalanceUtil.buildInternalIdealState(testDB0_1);
     
     result = TestEspressoStorageClusterIdealState.compareResult(resultOld, resultNew);
     masterKeepRatio = result[0];

http://git-wip-us.apache.org/repos/asf/incubator-helix/blob/80e9c4a9/helix-core/src/test/java/org/apache/helix/integration/TestRenamePartition.java
----------------------------------------------------------------------
diff --git a/helix-core/src/test/java/org/apache/helix/integration/TestRenamePartition.java b/helix-core/src/test/java/org/apache/helix/integration/TestRenamePartition.java
index 60c843b..4e52444 100644
--- a/helix-core/src/test/java/org/apache/helix/integration/TestRenamePartition.java
+++ b/helix-core/src/test/java/org/apache/helix/integration/TestRenamePartition.java
@@ -33,7 +33,7 @@ import org.apache.helix.manager.zk.ZkBaseDataAccessor;
 import org.apache.helix.mock.participant.MockParticipant;
 import org.apache.helix.model.IdealState;
 import org.apache.helix.tools.ClusterStateVerifier;
-import org.apache.helix.tools.IdealStateCalculatorForStorageNode;
+import org.apache.helix.tools.DefaultIdealStateCalculator;
 import org.testng.Assert;
 import org.testng.annotations.Test;
 
@@ -95,7 +95,7 @@ public class TestRenamePartition extends ZkIntegrationTestBase
     // calculate idealState
     List<String> instanceNames = Arrays.asList("localhost_12918", "localhost_12919", "localhost_12920",
         "localhost_12921", "localhost_12922");
-    ZNRecord destIS = IdealStateCalculatorForStorageNode.calculateIdealState(instanceNames,
+    ZNRecord destIS = DefaultIdealStateCalculator.calculateIdealState(instanceNames,
         10, 3-1, "TestDB0", "MASTER", "SLAVE");
     IdealState idealState = new IdealState(destIS);
     idealState.setIdealStateMode("CUSTOMIZED");

http://git-wip-us.apache.org/repos/asf/incubator-helix/blob/80e9c4a9/helix-core/src/test/java/org/apache/helix/josql/TestClusterJosqlQueryProcessor.java
----------------------------------------------------------------------
diff --git a/helix-core/src/test/java/org/apache/helix/josql/TestClusterJosqlQueryProcessor.java b/helix-core/src/test/java/org/apache/helix/josql/TestClusterJosqlQueryProcessor.java
index 06e85bb..3b8d29c 100644
--- a/helix-core/src/test/java/org/apache/helix/josql/TestClusterJosqlQueryProcessor.java
+++ b/helix-core/src/test/java/org/apache/helix/josql/TestClusterJosqlQueryProcessor.java
@@ -31,7 +31,7 @@ import org.apache.helix.ZNRecord;
 import org.apache.helix.josql.ZNRecordJosqlFunctionHandler;
 import org.apache.helix.josql.ZNRecordRow;
 import org.apache.helix.model.LiveInstance.LiveInstanceProperty;
-import org.apache.helix.tools.IdealStateCalculatorForStorageNode;
+import org.apache.helix.tools.DefaultIdealStateCalculator;
 import org.josql.Query;
 import org.josql.QueryExecutionException;
 import org.josql.QueryParseException;
@@ -60,7 +60,7 @@ public class TestClusterJosqlQueryProcessor
     }
     
     //liveInstances.remove(0);
-    ZNRecord externalView = IdealStateCalculatorForStorageNode.calculateIdealState(
+    ZNRecord externalView = DefaultIdealStateCalculator.calculateIdealState(
         instances, 21, 3, "TestDB", "MASTER", "SLAVE");
     
     

http://git-wip-us.apache.org/repos/asf/incubator-helix/blob/80e9c4a9/helix-core/src/test/java/org/apache/helix/messaging/TestDefaultMessagingService.java
----------------------------------------------------------------------
diff --git a/helix-core/src/test/java/org/apache/helix/messaging/TestDefaultMessagingService.java b/helix-core/src/test/java/org/apache/helix/messaging/TestDefaultMessagingService.java
index a2a609f..d99ee2f 100644
--- a/helix-core/src/test/java/org/apache/helix/messaging/TestDefaultMessagingService.java
+++ b/helix-core/src/test/java/org/apache/helix/messaging/TestDefaultMessagingService.java
@@ -39,7 +39,7 @@ import org.apache.helix.messaging.handling.MessageHandlerFactory;
 import org.apache.helix.model.ExternalView;
 import org.apache.helix.model.LiveInstance.LiveInstanceProperty;
 import org.apache.helix.model.Message;
-import org.apache.helix.tools.IdealStateCalculatorForStorageNode;
+import org.apache.helix.tools.DefaultIdealStateCalculator;
 import org.testng.AssertJUnit;
 import org.testng.annotations.Test;
 
@@ -105,7 +105,7 @@ public class TestDefaultMessagingService
             UUID.randomUUID().toString());
         _liveInstances.add(metaData);
       }
-      _externalView = IdealStateCalculatorForStorageNode.calculateIdealState(
+      _externalView = DefaultIdealStateCalculator.calculateIdealState(
           _instances, _partitions, _replicas, _db, "MASTER", "SLAVE");
 
     }

http://git-wip-us.apache.org/repos/asf/incubator-helix/blob/80e9c4a9/helix-core/src/test/java/org/apache/helix/monitoring/mbeans/TestClusterStatusMonitor.java
----------------------------------------------------------------------
diff --git a/helix-core/src/test/java/org/apache/helix/monitoring/mbeans/TestClusterStatusMonitor.java b/helix-core/src/test/java/org/apache/helix/monitoring/mbeans/TestClusterStatusMonitor.java
index 0054541..68cbaac 100644
--- a/helix-core/src/test/java/org/apache/helix/monitoring/mbeans/TestClusterStatusMonitor.java
+++ b/helix-core/src/test/java/org/apache/helix/monitoring/mbeans/TestClusterStatusMonitor.java
@@ -30,7 +30,7 @@ import org.apache.helix.NotificationContext;
 import org.apache.helix.PropertyType;
 import org.apache.helix.ZNRecord;
 import org.apache.helix.model.LiveInstance.LiveInstanceProperty;
-import org.apache.helix.tools.IdealStateCalculatorForStorageNode;
+import org.apache.helix.tools.DefaultIdealStateCalculator;
 import org.testng.annotations.Test;
 
 
@@ -55,10 +55,10 @@ public class TestClusterStatusMonitor
         String instance = "localhost_"+(12918+i);
         _instances.add(instance);
       }
-      ZNRecord externalView = IdealStateCalculatorForStorageNode.calculateIdealState(
+      ZNRecord externalView = DefaultIdealStateCalculator.calculateIdealState(
           _instances, _partitions, _replicas, _db, "MASTER", "SLAVE");
 
-      ZNRecord externalView2 = IdealStateCalculatorForStorageNode.calculateIdealState(
+      ZNRecord externalView2 = DefaultIdealStateCalculator.calculateIdealState(
           _instances, 80, 2, _db2, "MASTER", "SLAVE");
 
     }
@@ -109,10 +109,10 @@ public class TestClusterStatusMonitor
           UUID.randomUUID().toString());
       _liveInstances.add(metaData);
     }
-    ZNRecord externalView = IdealStateCalculatorForStorageNode.calculateIdealState(
+    ZNRecord externalView = DefaultIdealStateCalculator.calculateIdealState(
         _instances, _partitions, _replicas, _db, "MASTER", "SLAVE");
 
-    ZNRecord externalView2 = IdealStateCalculatorForStorageNode.calculateIdealState(
+    ZNRecord externalView2 = DefaultIdealStateCalculator.calculateIdealState(
         _instances, 80, 2, "TestDB", "MASTER", "SLAVE");
 
     List<ZNRecord> externalViews = new ArrayList<ZNRecord>();

http://git-wip-us.apache.org/repos/asf/incubator-helix/blob/80e9c4a9/helix-core/src/test/java/org/apache/helix/monitoring/mbeans/TestResourceMonitor.java
----------------------------------------------------------------------
diff --git a/helix-core/src/test/java/org/apache/helix/monitoring/mbeans/TestResourceMonitor.java b/helix-core/src/test/java/org/apache/helix/monitoring/mbeans/TestResourceMonitor.java
index 3276513..9d50d51 100644
--- a/helix-core/src/test/java/org/apache/helix/monitoring/mbeans/TestResourceMonitor.java
+++ b/helix-core/src/test/java/org/apache/helix/monitoring/mbeans/TestResourceMonitor.java
@@ -35,7 +35,7 @@ import org.apache.helix.model.ExternalView;
 import org.apache.helix.model.IdealState;
 import org.apache.helix.model.LiveInstance.LiveInstanceProperty;
 import org.apache.helix.monitoring.mbeans.ResourceMonitor;
-import org.apache.helix.tools.IdealStateCalculatorForStorageNode;
+import org.apache.helix.tools.DefaultIdealStateCalculator;
 import org.testng.AssertJUnit;
 import org.testng.annotations.Test;
 
@@ -107,7 +107,7 @@ public class TestResourceMonitor
             UUID.randomUUID().toString());
 
       }
-      _idealState= IdealStateCalculatorForStorageNode.calculateIdealState(_instances,
+      _idealState= DefaultIdealStateCalculator.calculateIdealState(_instances,
                                                                           _partitions,
                                                                           _replicas,
                                                                           _dbName,


Mime
View raw message