Skip to content

Commit

Permalink
Refactor the interfaces of hard/soft constraints and a central place …
Browse files Browse the repository at this point in the history
…to keep the softConstraint weights
  • Loading branch information
i3wangyi committed Aug 19, 2019
1 parent e28bc75 commit 781bfef
Show file tree
Hide file tree
Showing 5 changed files with 88 additions and 116 deletions.

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,10 @@
* Evaluate a partition allocation proposal and return YES or NO based on the cluster context.
* Any proposal fails one or more hard constraints will be rejected.
*/
public interface HardConstraint {
enum FailureReason {
abstract class HardConstraint {
private final Type _type;

enum Type {
FAULT_ZONES_CONTAIN_SAME_PARTITION,
NODES_DEACTIVATED,
NODES_NO_TAG,
Expand All @@ -37,14 +39,23 @@ enum FailureReason {
NODES_CONTAIN_SAME_PARTITION,
}

HardConstraint(Type failureReason) {
_type = failureReason;
}

// child class could extend and customize the message
String getFailureReason() {
return _type.toString();
}

/**
* @return True if the proposed assignment is valid.
* Check if the replica could be assigned to the node
* @return True if the proposed assignment is valid; False otherwise
*/
boolean isAssignmentValid(AssignableNode node, AssignableReplica rep,
abstract boolean isAssignmentValid(AssignableNode node, AssignableReplica replica,
ClusterContext clusterContext);

/**
* @return Detail of the reason that the proposed assignment was rejected.
*/
FailureReason getFailureReason();
Type getType() {
return _type;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,23 +27,31 @@
* Evaluate a partition allocation proposal and return a score within the normalized range.
* A higher score means the proposal is more preferred.
*/
public interface SoftConstraint {
float MIN_SCORE = -1000.0f;
float MAX_SCORE = 1000.0f;
abstract class SoftConstraint {
private final Type _type;

/**
* The scoring function returns a score between MINIMAL_SCORE and MAXIMUM_SCORE, which is then weighted by the
* individual normalized constraint weights.
* Each individual constraint will define the meaning of MINIMAL_SCORE to MAXIMUM_SCORE differently.
*/
float assignmentScore(AssignableNode node, AssignableReplica rep, ClusterContext clusterContext);
SoftConstraint(Type type) {
_type = type;
}

enum Type {
LEAST_USED_NODE,
LEAST_PARTITION_COUNT,
LEAST_MOVEMENTS
}

/**
* Set the importance factor of the soft constraint.
* The more important it is, the more contribution it will make to the final evaluation.
* @param importance
* The scoring function returns a score between MINIMAL_SCORE and MAXIMUM_SCORE, which is then
* weighted by the
* individual normalized constraint weights.
* Each individual constraint will define the meaning of MINIMAL_SCORE to MAXIMUM_SCORE
* differently.
* @return float value representing the score
*/
void setConstraintImportance(float importance);
abstract float getAssignmentScore(AssignableNode node, AssignableReplica rep,
ClusterContext clusterContext);

float getConstraintImportance();
Type getType() {
return _type;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package org.apache.helix.controller.rebalancer.waged.constraints;

import java.util.Map;

import com.google.common.collect.ImmutableMap;

/**
* The class retrieves the offline model that defines the relative importance of soft constraints.
*/
class SoftConstraintWeightModel {
private float MIN_SCORE = Float.MIN_VALUE;
private float MAX_SCORE = Float.MAX_VALUE;
private static Map<SoftConstraint.Type, Float> MODEL;

static {
// TODO either define the weights in property files or zookeeper node or static human input
MODEL = ImmutableMap.<SoftConstraint.Type, Float> builder()
.put(SoftConstraint.Type.LEAST_MOVEMENTS, 1.0f)
.put(SoftConstraint.Type.LEAST_PARTITION_COUNT, 1.0f)
.put(SoftConstraint.Type.LEAST_USED_NODE, 1.0f).build();
}

interface ScoreScaler {
/**
* Method to scale the origin score to a normalized range
* @param originScore The origin score of a range
* @return The normalized value between 0 - 1
*/
float scale(float originScore);
}

private ScoreScaler MIN_MAX_SCALER =
originScore -> (originScore - MIN_SCORE) / (MAX_SCORE - MIN_SCORE);

/**
* Given the calculated scores map by soft constraints, get the sum of scores
* @param originScoresMap The origin scores of soft constraints
* @return The sum of double type
*/
double getSumOfScores(Map<SoftConstraint, Float> originScoresMap) {
return originScoresMap.entrySet().stream().map(constraintToOriginScore -> {
float score = MIN_MAX_SCALER.scale(constraintToOriginScore.getValue());
float weight = MODEL.get(constraintToOriginScore.getKey().getType());
return score * weight;
}).mapToDouble(i -> i).sum();
}
}

0 comments on commit 781bfef

Please sign in to comment.