BestPossibleStateOutput output = new BestPossibleStateOutput();
for (String resourceName : resourceMap.keySet()) {
logger.debug("Processing resource:" + resourceName);
Resource resource = resourceMap.get(resourceName);
// Ideal state may be gone. In that case we need to get the state model name
// from the current state
IdealState idealState = cache.getIdealState(resourceName);
if (idealState == null) {
// if ideal state is deleted, use an empty one
logger.info("resource:" + resourceName + " does not exist anymore");
idealState = new IdealState(resourceName);
idealState.setStateModelDefRef(resource.getStateModelDefRef());
}
Rebalancer rebalancer = null;
MappingCalculator mappingCalculator = null;
switch (idealState.getRebalanceMode()) {
case FULL_AUTO:
AutoRebalancer autoRebalancer = new AutoRebalancer();
rebalancer = autoRebalancer;
mappingCalculator = autoRebalancer;
break;
case SEMI_AUTO:
SemiAutoRebalancer semiAutoRebalancer = new SemiAutoRebalancer();
rebalancer = semiAutoRebalancer;
mappingCalculator = semiAutoRebalancer;
break;
case CUSTOMIZED:
CustomRebalancer customRebalancer = new CustomRebalancer();
rebalancer = customRebalancer;
mappingCalculator = customRebalancer;
break;
case USER_DEFINED:
case TASK:
String rebalancerClassName = idealState.getRebalancerClassName();
logger
.info("resource " + resourceName + " use idealStateRebalancer " + rebalancerClassName);
try {
rebalancer =
Rebalancer.class.cast(HelixUtil.loadClass(getClass(), rebalancerClassName)
.newInstance());
} catch (Exception e) {
logger.warn("Exception while invoking custom rebalancer class:" + rebalancerClassName, e);
}
if (rebalancer != null) {
try {
mappingCalculator = MappingCalculator.class.cast(rebalancer);
} catch (ClassCastException e) {
logger.info("Rebalancer does not have a mapping calculator, defaulting to SEMI_AUTO");
}
}
if (mappingCalculator == null) {
mappingCalculator = new SemiAutoRebalancer();
}
break;
default:
break;
}
if (rebalancer != null && mappingCalculator != null) {
try {
HelixManager manager = event.getAttribute("helixmanager");
rebalancer.init(manager);
idealState =
rebalancer.computeNewIdealState(resourceName, idealState, currentStateOutput, cache);
// Use the internal MappingCalculator interface to compute the final assignment
// The next release will support rebalancers that compute the mapping from start to finish
ResourceAssignment partitionStateAssignment =
mappingCalculator.computeBestPossiblePartitionState(cache, idealState, resource,
currentStateOutput);
for (Partition partition : resource.getPartitions()) {
Map<String, String> newStateMap = partitionStateAssignment.getReplicaMap(partition);
output.setState(resourceName, partition, newStateMap);
}
} catch (Exception e) {
logger