[GitHub] [helix] jiajunwang commented on issue #342: Kickoff for the Weight Aware Globally Even Distribute Rebalancer

2019-08-02 Thread GitBox
jiajunwang commented on issue #342: Kickoff for the Weight Aware Globally Even 
Distribute Rebalancer
URL: https://github.com/apache/helix/issues/342#issuecomment-517893119
 
 
   The foundation of the new rebalancer has been built after the 
interface/cluster model checked in. I'm closing this issue since we will have 
separate issues to track the following components development.


This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
us...@infra.apache.org


With regards,
Apache Git Services


[GitHub] [helix] jiajunwang closed issue #342: Kickoff for the Weight Aware Globally Even Distribute Rebalancer

2019-08-02 Thread GitBox
jiajunwang closed issue #342: Kickoff for the Weight Aware Globally Even 
Distribute Rebalancer
URL: https://github.com/apache/helix/issues/342
 
 
   


This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
us...@infra.apache.org


With regards,
Apache Git Services


[GitHub] [helix] jiajunwang merged pull request #362: The WAGED rebalancer cluster model implementation

2019-08-02 Thread GitBox
jiajunwang merged pull request #362: The WAGED rebalancer cluster model 
implementation
URL: https://github.com/apache/helix/pull/362
 
 
   


This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
us...@infra.apache.org


With regards,
Apache Git Services


[GitHub] [helix] jiajunwang commented on issue #362: The WAGED rebalancer cluster model implementation

2019-08-02 Thread GitBox
jiajunwang commented on issue #362: The WAGED rebalancer cluster model 
implementation
URL: https://github.com/apache/helix/pull/362#issuecomment-517892944
 
 
   This PR is ready to be merged, approved by @narendly.
   
   I will do the merge.


This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
us...@infra.apache.org


With regards,
Apache Git Services


[GitHub] [helix] jiajunwang commented on a change in pull request #362: The WAGED rebalancer cluster model implementation

2019-08-02 Thread GitBox
jiajunwang commented on a change in pull request #362: The WAGED rebalancer 
cluster model implementation
URL: https://github.com/apache/helix/pull/362#discussion_r310338335
 
 

 ##
 File path: 
helix-core/src/main/java/org/apache/helix/controller/rebalancer/waged/model/AssignableReplica.java
 ##
 @@ -19,9 +19,119 @@
  * under the License.
  */
 
+import org.apache.helix.model.ResourceConfig;
+import org.apache.helix.model.StateModelDefinition;
+
+import java.io.IOException;
+import java.util.Map;
+
 /**
- * A placeholder before we have the implementation.
- *
  * This class represents a partition replication that needs to be allocated.
  */
-public class AssignableReplica { }
+public class AssignableReplica implements Comparable {
+  private final String _partitionName;
+  private final String _resourceName;
+  private final String _resourceInstanceGroupTag;
+  private final int _resourceMaxPartitionsPerInstance;
+  private final Map _capacityUsage;
+  // The priority of the replica's state
+  private final int _statePriority;
+  // The state of the replica
+  private final String _replicaState;
+
 
 Review comment:
   The rebalance logic will take care of the resource, partition, and also 
state priority.
   The priority we recorded in the replica is mainly for the top state. Since 
that is really something special.
   In fact, I tried to use a boolean isTopState. But then I find the number of 
priority already exists and it is the most direct information. The model class 
shall not do extra calculation.


This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
us...@infra.apache.org


With regards,
Apache Git Services


[GitHub] [helix] narendly commented on a change in pull request #362: The WAGED rebalancer cluster model implementation

2019-08-02 Thread GitBox
narendly commented on a change in pull request #362: The WAGED rebalancer 
cluster model implementation
URL: https://github.com/apache/helix/pull/362#discussion_r310336821
 
 

 ##
 File path: 
helix-core/src/main/java/org/apache/helix/controller/rebalancer/waged/model/AssignableReplica.java
 ##
 @@ -19,9 +19,121 @@
  * under the License.
  */
 
+import org.apache.helix.model.ResourceConfig;
+import org.apache.helix.model.StateModelDefinition;
+
+import java.io.IOException;
+import java.util.Map;
+
 /**
- * A placeholder before we have the implementation.
- *
  * This class represents a partition replication that needs to be allocated.
  */
-public class AssignableReplica { }
+public class AssignableReplica implements Comparable {
+  private final String _partitionName;
+  private final String _resourceName;
+  private final String _resourceInstanceGroupTag;
+  private final int _resourceMaxPartitionsPerInstance;
+  private final Map _capacityUsage;
+  // The priority of the replica's state
+  private final int _statePriority;
+  // The state of the replica
+  private final String _replicaState;
+
+  /**
+   * @param resourceConfig The resource config for the resource which contains 
the replication.
+   * @param partitionName  The replication's partition name.
+   * @param replicaState   The state of the replication.
+   * @param statePriority  The priority of the replication's state.
+   */
+  AssignableReplica(ResourceConfig resourceConfig, String partitionName, 
String replicaState,
+  int statePriority) {
+_partitionName = partitionName;
+_replicaState = replicaState;
+_statePriority = statePriority;
+_resourceName = resourceConfig.getResourceName();
+_capacityUsage = fetchCapacityUsage(partitionName, resourceConfig);
 
 Review comment:
   I would only advocate for the Builder pattern if there were more arguments 
(or if we expect to add more arguments to the constructor). To me, this is OK.


This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
us...@infra.apache.org


With regards,
Apache Git Services


[GitHub] [helix] narendly commented on a change in pull request #362: The WAGED rebalancer cluster model implementation

2019-08-02 Thread GitBox
narendly commented on a change in pull request #362: The WAGED rebalancer 
cluster model implementation
URL: https://github.com/apache/helix/pull/362#discussion_r310336903
 
 

 ##
 File path: 
helix-core/src/test/java/org/apache/helix/controller/rebalancer/waged/model/AbstractTestClusterModel.java
 ##
 @@ -0,0 +1,161 @@
+package org.apache.helix.controller.rebalancer.waged.model;
+
+/*
+ * 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 
org.apache.helix.controller.dataproviders.ResourceControllerDataProvider;
+import org.apache.helix.model.BuiltInStateModelDefinitions;
+import org.apache.helix.model.ClusterConfig;
+import org.apache.helix.model.CurrentState;
+import org.apache.helix.model.InstanceConfig;
+import org.apache.helix.model.LiveInstance;
+import org.apache.helix.model.ResourceConfig;
+import org.mockito.Mockito;
+import org.testng.annotations.BeforeClass;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import static org.mockito.Mockito.when;
+
+public abstract class AbstractTestClusterModel {
+  protected String _testInstanceId;
+  protected List _resourceNames;
+  protected List _partitionNames;
+  protected Map _capacityDataMap;
+  protected Map> _disabledPartitionsMap;
+  protected List _testInstanceTags;
+  protected String _testFaultZoneId;
+
+  @BeforeClass
+  public void initialize() {
+_testInstanceId = "testInstanceId";
+_resourceNames = new ArrayList<>();
+_resourceNames.add("Resource1");
+_resourceNames.add("Resource2");
+_partitionNames = new ArrayList<>();
+_partitionNames.add("Partition1");
+_partitionNames.add("Partition2");
+_partitionNames.add("Partition3");
+_partitionNames.add("Partition4");
+_capacityDataMap = new HashMap<>();
+_capacityDataMap.put("item1", 20);
+_capacityDataMap.put("item2", 40);
+_capacityDataMap.put("item3", 30);
+List disabledPartitions = new ArrayList<>();
+disabledPartitions.add("TestPartition");
+_disabledPartitionsMap = new HashMap<>();
+_disabledPartitionsMap.put("TestResource", disabledPartitions);
+_testInstanceTags = new ArrayList<>();
+_testInstanceTags.add("TestTag");
+_testFaultZoneId = "testZone";
+  }
+
+  protected ResourceControllerDataProvider setupClusterDataCache() throws 
IOException {
 
 Review comment:
   I like the descriptive comments. Thanks :)


This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
us...@infra.apache.org


With regards,
Apache Git Services


[GitHub] [helix] narendly commented on a change in pull request #362: The WAGED rebalancer cluster model implementation

2019-08-02 Thread GitBox
narendly commented on a change in pull request #362: The WAGED rebalancer 
cluster model implementation
URL: https://github.com/apache/helix/pull/362#discussion_r310336872
 
 

 ##
 File path: 
helix-core/src/main/java/org/apache/helix/controller/rebalancer/waged/model/ClusterModel.java
 ##
 @@ -19,9 +19,131 @@
  * under the License.
  */
 
+import org.apache.helix.HelixException;
+import org.apache.helix.model.IdealState;
+
+import java.util.Collections;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
+
 /**
- * A placeholder before we have the implementation.
- *
  * This class wraps the required input for the rebalance algorithm.
  */
-public class ClusterModel { }
+public class ClusterModel {
+  private final ClusterContext _clusterContext;
+  // Map to track all the assignable replications. >
+  private final Map> _assignableReplicas;
+  // The index to find the replication information with a certain state. 
>
+  // Note that the identical replicas are dedupe in the index.
+  private final Map> 
_assignableReplicaIndex;
+  private final Map _assignableNodeMap;
+
+  // Records about the previous assignment
+  private final Map _baselineAssignment;
+  private final Map _bestPossibleAssignment;
+
+  /**
+   * @param clusterContext The initialized cluster context.
+   * @param assignableReplicas The replications to be assigned.
+   *   Note that the replicas in this list shall 
not be included while initializing the context and assignable nodes.
+   * @param assignableNodesThe active instances.
+   * @param baselineAssignment The recorded baseline assignment.
+   * @param bestPossibleAssignment The current best possible assignment.
+   */
+  ClusterModel(ClusterContext clusterContext, Set 
assignableReplicas,
+  Set assignableNodes, Map 
baselineAssignment,
+  Map bestPossibleAssignment) {
+_clusterContext = clusterContext;
+
+// Save all the to be assigned replication
+_assignableReplicas = assignableReplicas.stream()
+.collect(Collectors.groupingBy(AssignableReplica::getResourceName, 
Collectors.toSet()));
+
+// Index all the replicas to be assigned. Dedup the replica if two 
instances have the same resource/partition/state
+_assignableReplicaIndex = assignableReplicas.stream().collect(Collectors
+.groupingBy(AssignableReplica::getResourceName, Collectors
+.toMap(AssignableReplica::toString, replica -> replica,
+(oldValue, newValue) -> oldValue)));
+
+_assignableNodeMap = assignableNodes.stream()
+.collect(Collectors.toMap(AssignableNode::getInstanceName, node -> 
node));
+
+_baselineAssignment = baselineAssignment;
+_bestPossibleAssignment = bestPossibleAssignment;
+  }
+
+  public ClusterContext getContext() {
+return _clusterContext;
+  }
+
+  public Map getAssignableNodes() {
+return _assignableNodeMap;
+  }
+
+  public Map> getAssignableReplicas() {
+return _assignableReplicas;
+  }
+
+  public Map getBaseline() {
+return _baselineAssignment;
+  }
+
+  public Map getBestPossibleAssignment() {
+return _bestPossibleAssignment;
+  }
+
+  /**
+   * Propose the assignment to the cluster model.
+   *
+   * @param resourceName
+   * @param partitionName
+   * @param state
+   * @param instanceName
+   */
+  public void assign(String resourceName, String partitionName, String state, 
String instanceName) {
+AssignableNode node = locateAssignableNode(instanceName);
+AssignableReplica replica = locateAssignableReplica(resourceName, 
partitionName, state);
+
+node.assign(replica);
+_clusterContext.addPartitionToFaultZone(node.getFaultZone(), resourceName, 
partitionName);
+  }
+
+  /**
+   * Revert the proposed assignment from the cluster model.
+   *
+   * @param resourceName
+   * @param partitionName
+   * @param state
+   * @param instanceName
+   */
+  public void release(String resourceName, String partitionName, String state,
+  String instanceName) {
+AssignableNode node = locateAssignableNode(instanceName);
+AssignableReplica replica = locateAssignableReplica(resourceName, 
partitionName, state);
+
+node.release(replica);
+_clusterContext.removePartitionFromFaultZone(node.getFaultZone(), 
resourceName, partitionName);
+  }
+
+  private AssignableNode locateAssignableNode(String instanceName) {
+AssignableNode node = _assignableNodeMap.get(instanceName);
+if (node == null) {
+  throw new HelixException("Cannot find the instance: " + instanceName);
 
 Review comment:
   Sorry I don't think I understand. 
   This is a private method so I don't think anyone is going to call it but us, 
but what would it mean when an AssignableNode is not found for the given 
instanceName? Would that be an indication that we messed up somewhere?


This is an automated message from the Apache Git 

[GitHub] [helix] narendly commented on a change in pull request #362: The WAGED rebalancer cluster model implementation

2019-08-02 Thread GitBox
narendly commented on a change in pull request #362: The WAGED rebalancer 
cluster model implementation
URL: https://github.com/apache/helix/pull/362#discussion_r310336640
 
 

 ##
 File path: 
helix-core/src/main/java/org/apache/helix/controller/rebalancer/waged/model/AssignableReplica.java
 ##
 @@ -19,9 +19,119 @@
  * under the License.
  */
 
+import org.apache.helix.model.ResourceConfig;
+import org.apache.helix.model.StateModelDefinition;
+
+import java.io.IOException;
+import java.util.Map;
+
 /**
- * A placeholder before we have the implementation.
- *
  * This class represents a partition replication that needs to be allocated.
  */
-public class AssignableReplica { }
+public class AssignableReplica implements Comparable {
+  private final String _partitionName;
+  private final String _resourceName;
+  private final String _resourceInstanceGroupTag;
+  private final int _resourceMaxPartitionsPerInstance;
+  private final Map _capacityUsage;
+  // The priority of the replica's state
+  private final int _statePriority;
+  // The state of the replica
+  private final String _replicaState;
+
 
 Review comment:
   I think I was thinking about priority among different partitions. I don't 
know how the assignment logic works (is it part of this PR or is it TBD in 
another PR?), but I agree with you if we assign replicas by partition. 
   
   I was just bringing up the fact that we may need to account partition-level 
or resource-level priority at assign time. OK to resolve this issue since we 
could always revisit later.


This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
us...@infra.apache.org


With regards,
Apache Git Services


[GitHub] [helix] narendly commented on a change in pull request #362: The WAGED rebalancer cluster model implementation

2019-08-02 Thread GitBox
narendly commented on a change in pull request #362: The WAGED rebalancer 
cluster model implementation
URL: https://github.com/apache/helix/pull/362#discussion_r310336694
 
 

 ##
 File path: 
helix-core/src/main/java/org/apache/helix/controller/rebalancer/waged/model/AssignableNode.java
 ##
 @@ -19,10 +19,287 @@
  * under the License.
  */
 
+import org.apache.helix.HelixException;
+import org.apache.helix.model.ClusterConfig;
+import org.apache.helix.model.InstanceConfig;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import static java.lang.Math.max;
+
 /**
- * A placeholder before we have the implementation.
- *
- * This class represents a potential allocation of the replication.
- * Note that AssignableNode is not thread safe.
+ * This class represents a possible allocation of the replication.
+ * Note that any usage updates to the AssignableNode are not thread safe.
  */
-public class AssignableNode { }
+public class AssignableNode {
+  private static final Logger LOG = 
LoggerFactory.getLogger(AssignableNode.class.getName());
+
+  // basic node information
+  private final String _instanceName;
+  private Set _instanceTags;
+  private String _faultZone;
+  private Map> _disabledPartitionsMap;
+  private Map _maxCapacity;
+  private int _maxPartition; // maximum number of the partitions that can be 
assigned to the node.
+
+  // proposed assignment tracking
+  // 
+  private Map> _currentAssignments;
+  // 
+  private Map> _currentTopStateAssignments;
+  // 
+  private Map _currentCapacity;
+  // The maximum capacity utilization (0.0 - 1.0) across all the capacity 
categories.
+  private float _highestCapacityUtilization;
+
+  AssignableNode(ClusterConfig clusterConfig, InstanceConfig instanceConfig, 
String instanceName,
+  Collection existingAssignment) {
+_instanceName = instanceName;
+refresh(clusterConfig, instanceConfig, existingAssignment);
+  }
+
+  private void reset() {
+_currentAssignments = new HashMap<>();
+_currentTopStateAssignments = new HashMap<>();
+_currentCapacity = new HashMap<>();
+_highestCapacityUtilization = 0;
+  }
+
+  /**
+   * Update the node with a ClusterDataCache. This resets the current 
assignment and recalculates currentCapacity.
+   * NOTE: While this is required to be used in the constructor, this can also 
be used when the clusterCache needs to be
+   * refreshed. This is under the assumption that the capacity mappings of 
InstanceConfig and ResourceConfig could
+   * subject to change. If the assumption is no longer true, this function 
should become private.
+   *
+   * @param clusterConfig  - the Cluster Config of the cluster where the node 
is located
+   * @param instanceConfig - the Instance Config of the node
+   * @param existingAssignment - all the existing replicas that are current 
assigned to the node
+   */
+  private void refresh(ClusterConfig clusterConfig, InstanceConfig 
instanceConfig,
+  Collection existingAssignment) {
+reset();
+
+_currentCapacity.putAll(instanceConfig.getInstanceCapacityMap());
+_faultZone = computeFaultZone(clusterConfig, instanceConfig);
+_instanceTags = new HashSet<>(instanceConfig.getTags());
+_disabledPartitionsMap = instanceConfig.getDisabledPartitionsMap();
+_maxCapacity = instanceConfig.getInstanceCapacityMap();
+_maxPartition = clusterConfig.getMaxPartitionsPerInstance();
+
+assignNewBatch(existingAssignment);
+  }
+
+  /**
+   * Assign a replica to the node.
+   *
+   * @param assignableReplica - the replica to be assigned
+   */
+  void assign(AssignableReplica assignableReplica) {
+if (!addToAssignmentRecord(assignableReplica, _currentAssignments)) {
+  throw new HelixException(String
+  .format("Resource %s already has a replica from partition %s on node 
%s",
+  assignableReplica.getResourceName(), 
assignableReplica.getPartitionName(),
+  getInstanceName()));
+} else {
+  if (assignableReplica.isReplicaTopState()) {
+addToAssignmentRecord(assignableReplica, _currentTopStateAssignments);
+  }
+  assignableReplica.getCapacity().entrySet().stream().forEach(
+  capacity -> updateCapacityAndUtilization(capacity.getKey(), 
capacity.getValue()));
+}
+  }
+
+  /**
+   * Release a replica from the node.
+   * If the replication is not on this node, the assignable node is not 
updated.
+   *
+   * @param assignableReplica - the replica to be released
+   */
+  void release(AssignableReplica assignableReplica) throws 
IllegalArgumentException {
+String resourceName = assignableReplica.getResourceName();
+String partitionName = assignableReplica.getPartitionName();
+
+// Check if the release is necessary
+if 

[GitHub] [helix] narendly commented on a change in pull request #362: The WAGED rebalancer cluster model implementation

2019-08-02 Thread GitBox
narendly commented on a change in pull request #362: The WAGED rebalancer 
cluster model implementation
URL: https://github.com/apache/helix/pull/362#discussion_r310336640
 
 

 ##
 File path: 
helix-core/src/main/java/org/apache/helix/controller/rebalancer/waged/model/AssignableReplica.java
 ##
 @@ -19,9 +19,119 @@
  * under the License.
  */
 
+import org.apache.helix.model.ResourceConfig;
+import org.apache.helix.model.StateModelDefinition;
+
+import java.io.IOException;
+import java.util.Map;
+
 /**
- * A placeholder before we have the implementation.
- *
  * This class represents a partition replication that needs to be allocated.
  */
-public class AssignableReplica { }
+public class AssignableReplica implements Comparable {
+  private final String _partitionName;
+  private final String _resourceName;
+  private final String _resourceInstanceGroupTag;
+  private final int _resourceMaxPartitionsPerInstance;
+  private final Map _capacityUsage;
+  // The priority of the replica's state
+  private final int _statePriority;
+  // The state of the replica
+  private final String _replicaState;
+
 
 Review comment:
   I think I was thinking about priority among different partitions. I don't 
know how the assignment logic works (is it part of this PR or is it TBD in 
another PR?), but I agree with you if we assign replicas by partition. 
   
   I was just bringing up the fact that we may need to account partition-level 
or resource-level priority at assign time.


This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
us...@infra.apache.org


With regards,
Apache Git Services


[GitHub] [helix] narendly commented on a change in pull request #362: The WAGED rebalancer cluster model implementation

2019-08-02 Thread GitBox
narendly commented on a change in pull request #362: The WAGED rebalancer 
cluster model implementation
URL: https://github.com/apache/helix/pull/362#discussion_r310336585
 
 

 ##
 File path: 
helix-core/src/main/java/org/apache/helix/controller/rebalancer/waged/model/AssignableNode.java
 ##
 @@ -19,10 +19,293 @@
  * under the License.
  */
 
+import org.apache.helix.HelixException;
+import 
org.apache.helix.controller.dataproviders.ResourceControllerDataProvider;
+import org.apache.helix.model.ClusterConfig;
+import org.apache.helix.model.InstanceConfig;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import static java.lang.Math.max;
+
 /**
- * A placeholder before we have the implementation.
- *
- * This class represents a potential allocation of the replication.
- * Note that AssignableNode is not thread safe.
+ * This class represents a possible allocation of the replication.
+ * Note that any usage updates to the AssignableNode are not thread safe.
  */
-public class AssignableNode { }
+public class AssignableNode {
+  private static final Logger _logger = 
LoggerFactory.getLogger(AssignableNode.class.getName());
+
+  // basic node information
+  private final String _instanceName;
+  private Set _instanceTags;
+  private String _faultZone;
+  private Map> _disabledPartitionsMap;
+  private Map _maxCapacity;
+  private int _maxPartition;
+
+  // proposed assignment tracking
+  // 
+  private Map> _currentAssignments;
+  // 
+  private Map> _currentTopStateAssignments;
+  // 
+  private Map _currentCapacity;
+  // runtime usage tracking
+  private int _totalReplicaAssignmentCount;
+  private float _highestCapacityUtilization;
+
+  AssignableNode(ResourceControllerDataProvider clusterCache, String 
instanceName,
+  Collection existingAssignment) {
+_instanceName = instanceName;
+refresh(clusterCache, existingAssignment);
+  }
+
+  private void reset() {
+_currentAssignments = new HashMap<>();
+_currentTopStateAssignments = new HashMap<>();
+_currentCapacity = new HashMap<>();
+_totalReplicaAssignmentCount = 0;
+_highestCapacityUtilization = 0;
+  }
+
+  /**
+   * Update the node with a ClusterDataCache. This resets the current 
assignment and recalculate currentCapacity.
+   * NOTE: While this is required to be used in the constructor, this can also 
be used when the clusterCache needs to be
+   * refreshed. This is under the assumption that the capacity mappings of 
InstanceConfig and ResourceConfig could
+   * subject to changes. If the assumption is no longer true, this function 
should become private.
+   *
+   * @param clusterCache - the current cluster cache to initial the 
AssignableNode.
+   */
+  private void refresh(ResourceControllerDataProvider clusterCache,
+  Collection existingAssignment) {
+reset();
+
+InstanceConfig instanceConfig = 
clusterCache.getInstanceConfigMap().get(_instanceName);
+ClusterConfig clusterConfig = clusterCache.getClusterConfig();
+
+_currentCapacity.putAll(instanceConfig.getInstanceCapacityMap());
+_faultZone = computeFaultZone(clusterConfig, instanceConfig);
+_instanceTags = new HashSet<>(instanceConfig.getTags());
+_disabledPartitionsMap = instanceConfig.getDisabledPartitionsMap();
+_maxCapacity = instanceConfig.getInstanceCapacityMap();
+_maxPartition = clusterConfig.getMaxPartitionsPerInstance();
+
+assignNewBatch(existingAssignment);
+  }
+
+  /**
+   * Assign a replica to the node.
+   *
+   * @param assignableReplica - the replica to be assigned
+   */
+  void assign(AssignableReplica assignableReplica) {
+if (!addToAssignmentRecord(assignableReplica, _currentAssignments)) {
+  throw new HelixException(String
+  .format("Resource %s already has a replica from partition %s on this 
node",
+  assignableReplica.getResourceName(), 
assignableReplica.getPartitionName()));
+} else {
+  if (assignableReplica.isReplicaTopState()) {
+addToAssignmentRecord(assignableReplica, _currentTopStateAssignments);
+  }
+  _totalReplicaAssignmentCount += 1;
+  assignableReplica.getCapacity().entrySet().stream()
+  .forEach(entry -> updateCapacityAndUtilization(entry.getKey(), 
entry.getValue()));
+}
+  }
+
+  /**
+   * Release a replica from the node.
+   * If the replication is not on this node, the assignable node is not 
updated.
+   *
+   * @param assignableReplica - the replica to be released
+   */
+  void release(AssignableReplica assignableReplica) throws 
IllegalArgumentException {
+String resourceName = assignableReplica.getResourceName();
+String partitionName = assignableReplica.getPartitionName();
+
+// Check if the release is necessary
+if 

[GitHub] [helix] jiajunwang opened a new issue #372: Implement the Cluster Model data provider for the WAGED rebalancer

2019-08-02 Thread GitBox
jiajunwang opened a new issue #372: Implement the Cluster Model data provider 
for the WAGED rebalancer
URL: https://github.com/apache/helix/issues/372
 
 
   Please find the design doc here:
   
https://github.com/apache/helix/wiki/Design-Proposal---Weight-Aware-Globally-Even-Distribute-Rebalancer
   
   This data provider will help to convert Helix cluster status data into the 
rebalancer readable Cluster Model object. The result will be used to support 
rebalance calculation.
   
   AC:
   - finish the implementation based on the design.
   - add unit tests for the new data provider.


This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
us...@infra.apache.org


With regards,
Apache Git Services


[GitHub] [helix] jiajunwang commented on issue #362: The WAGED rebalancer cluster model implementation

2019-08-02 Thread GitBox
jiajunwang commented on issue #362: The WAGED rebalancer cluster model 
implementation
URL: https://github.com/apache/helix/pull/362#issuecomment-517854427
 
 
   Thanks for your hard work of reviewing.
   I know it is a huge PR. Mainly because it is new classes that are built from 
scratch, even one file's change has been large enough. And as the initial 
interface checking, I wish to keep then in one PR.
   
   The following functional components will still be a large file, but they 
will be loosely coupled. So we will be able to make relatively smaller PR.


This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
us...@infra.apache.org


With regards,
Apache Git Services


[GitHub] [helix] jiajunwang commented on a change in pull request #362: The WAGED rebalancer cluster model implementation

2019-08-02 Thread GitBox
jiajunwang commented on a change in pull request #362: The WAGED rebalancer 
cluster model implementation
URL: https://github.com/apache/helix/pull/362#discussion_r310284240
 
 

 ##
 File path: 
helix-core/src/main/java/org/apache/helix/controller/rebalancer/waged/model/AssignableNode.java
 ##
 @@ -19,10 +19,290 @@
  * under the License.
  */
 
+import org.apache.helix.HelixException;
+import 
org.apache.helix.controller.dataproviders.ResourceControllerDataProvider;
+import org.apache.helix.model.ClusterConfig;
+import org.apache.helix.model.InstanceConfig;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import static java.lang.Math.max;
+
 /**
- * A placeholder before we have the implementation.
- *
- * This class represents a potential allocation of the replication.
- * Note that AssignableNode is not thread safe.
+ * This class represents a possible allocation of the replication.
+ * Note that any usage updates to the AssignableNode are not thread safe.
  */
-public class AssignableNode { }
+public class AssignableNode {
+  private static final Logger _logger = 
LoggerFactory.getLogger(AssignableNode.class.getName());
+
+  // proposed assignment tracking
+  // 
+  private Map> _currentAssignments;
+  // 
+  private Map> _currentTopStateAssignments;
+  // 
+  private Map _currentCapacity;
+  // runtime usage tracking
+  private int _totalReplicaAssignmentCount;
+  private float _highestCapacityUtilization;
+
+  // basic node information
+  private final String _instanceName;
+  private Set _instanceTags;
+  private String _faultZone;
+  private Map> _disabledPartitionsMap;
+  private Map _maxCapacity;
+  private int _maxPartition;
+
+  AssignableNode(ResourceControllerDataProvider clusterCache, String 
instanceName,
+  Collection existingAssignment) {
+_instanceName = instanceName;
+refresh(clusterCache, existingAssignment);
+  }
+
+  private void reset() {
+_currentAssignments = new HashMap<>();
+_currentTopStateAssignments = new HashMap<>();
+_currentCapacity = new HashMap<>();
+_totalReplicaAssignmentCount = 0;
+_highestCapacityUtilization = 0;
+  }
+
+  /**
+   * Update the node with a ClusterDataCache. This resets the current 
assignment and recalculate currentCapacity.
+   * NOTE: While this is required to be used in the constructor, this can also 
be used when the clusterCache needs to be
+   * refreshed. This is under the assumption that the capacity mappings of 
InstanceConfig and ResourceConfig could
+   * subject to changes. If the assumption is no longer true, this function 
should become private.
+   *
+   * @param clusterCache - the current cluster cache to initial the 
AssignableNode.
+   */
+  private void refresh(ResourceControllerDataProvider clusterCache,
 
 Review comment:
   Some background here. We want to have a cluster data cache snapshot based on 
DataProvider. And that should have been used here. The snapshot is immutable. 
Unfortunately, we don't have this class implemented yet.
   This provider the closest thing we can use for now. We will need to refactor 
the usage of the data provider everywhere once the snapshot is done. This is 
planed in the scope of controller improvement.
   
   About the second point, the data provider does not know anything about data 
model. This is the current situation. I guess you are saying that data model 
shall not rely on the data provider's methods, right?
   This is a valid call, let me try to change the refresh method parameters. 
But still, a builder is too complicated for now.


This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
us...@infra.apache.org


With regards,
Apache Git Services


[GitHub] [helix] jiajunwang commented on a change in pull request #362: The WAGED rebalancer cluster model implementation

2019-08-02 Thread GitBox
jiajunwang commented on a change in pull request #362: The WAGED rebalancer 
cluster model implementation
URL: https://github.com/apache/helix/pull/362#discussion_r310279995
 
 

 ##
 File path: 
helix-core/src/test/java/org/apache/helix/controller/rebalancer/waged/model/TestClusterContext.java
 ##
 @@ -0,0 +1,93 @@
+package org.apache.helix.controller.rebalancer.waged.model;
+
+/*
+ * 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 org.apache.helix.HelixException;
+import 
org.apache.helix.controller.dataproviders.ResourceControllerDataProvider;
+import org.testng.Assert;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+import java.io.IOException;
+import java.util.Collections;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import static java.util.stream.Collectors.toSet;
+
+public class TestClusterContext extends AbstractTestClusterModel {
+  @BeforeClass
+  public void initialize() {
+super.initialize();
+  }
+
+  @Test
+  public void testNormalUsage() throws IOException {
+ResourceControllerDataProvider testCache = setupClusterDataCache();
+Set assignmentSet = generateReplicas(testCache);
+
+// Test 1 - initialization
+ClusterContext context = new ClusterContext(assignmentSet, 2);
+
+// Note that we leaved some margin for the max estimation.
+Assert.assertEquals(context.getEstimatedMaxPartitionCount(), 3);
+Assert.assertEquals(context.getEstimatedMaxTopStateCount(), 2);
+Assert.assertEquals(context.getAssignmentForFaultZoneMap(), 
Collections.emptyMap());
+for (String resourceName : _resourceNames) {
+  
Assert.assertEquals(context.getEstimatedMaxPartitionByResource(resourceName), 
2);
+  Assert.assertEquals(
+  context.getPartitionsForResourceAndFaultZone(_testFaultZoneId, 
resourceName),
+  Collections.emptySet());
+}
+
+// Assign
+Map>> expectedFaultZoneMap = Collections
+.singletonMap(_testFaultZoneId, 
assignmentSet.stream().collect(Collectors
+.groupingBy(AssignableReplica::getResourceName,
+Collectors.mapping(AssignableReplica::getPartitionName, 
toSet();
+
+assignmentSet.stream().forEach(r -> context
+.addPartitionToFaultZone(_testFaultZoneId, r.getResourceName(), 
r.getPartitionName()));
+Assert.assertEquals(context.getAssignmentForFaultZoneMap(), 
expectedFaultZoneMap);
+
+// release
+
Assert.assertTrue(expectedFaultZoneMap.get(_testFaultZoneId).get(_resourceNames.get(0))
 
 Review comment:
   This is a typo. Good catch! Should check the next line.


This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
us...@infra.apache.org


With regards,
Apache Git Services


[GitHub] [helix] jiajunwang commented on a change in pull request #362: The WAGED rebalancer cluster model implementation

2019-08-02 Thread GitBox
jiajunwang commented on a change in pull request #362: The WAGED rebalancer 
cluster model implementation
URL: https://github.com/apache/helix/pull/362#discussion_r310280122
 
 

 ##
 File path: 
helix-core/src/test/java/org/apache/helix/controller/rebalancer/waged/model/TestClusterContext.java
 ##
 @@ -0,0 +1,93 @@
+package org.apache.helix.controller.rebalancer.waged.model;
+
+/*
+ * 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 org.apache.helix.HelixException;
+import 
org.apache.helix.controller.dataproviders.ResourceControllerDataProvider;
+import org.testng.Assert;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+import java.io.IOException;
+import java.util.Collections;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import static java.util.stream.Collectors.toSet;
+
+public class TestClusterContext extends AbstractTestClusterModel {
+  @BeforeClass
+  public void initialize() {
+super.initialize();
+  }
+
+  @Test
+  public void testNormalUsage() throws IOException {
+ResourceControllerDataProvider testCache = setupClusterDataCache();
+Set assignmentSet = generateReplicas(testCache);
+
+// Test 1 - initialization
+ClusterContext context = new ClusterContext(assignmentSet, 2);
+
+// Note that we leaved some margin for the max estimation.
+Assert.assertEquals(context.getEstimatedMaxPartitionCount(), 3);
+Assert.assertEquals(context.getEstimatedMaxTopStateCount(), 2);
+Assert.assertEquals(context.getAssignmentForFaultZoneMap(), 
Collections.emptyMap());
+for (String resourceName : _resourceNames) {
+  
Assert.assertEquals(context.getEstimatedMaxPartitionByResource(resourceName), 
2);
+  Assert.assertEquals(
+  context.getPartitionsForResourceAndFaultZone(_testFaultZoneId, 
resourceName),
+  Collections.emptySet());
+}
+
+// Assign
+Map>> expectedFaultZoneMap = Collections
+.singletonMap(_testFaultZoneId, 
assignmentSet.stream().collect(Collectors
+.groupingBy(AssignableReplica::getResourceName,
+Collectors.mapping(AssignableReplica::getPartitionName, 
toSet();
+
+assignmentSet.stream().forEach(r -> context
+.addPartitionToFaultZone(_testFaultZoneId, r.getResourceName(), 
r.getPartitionName()));
+Assert.assertEquals(context.getAssignmentForFaultZoneMap(), 
expectedFaultZoneMap);
+
+// release
+
Assert.assertTrue(expectedFaultZoneMap.get(_testFaultZoneId).get(_resourceNames.get(0))
+.remove(_partitionNames.get(0)));
+context.removePartitionFromFaultZone(_testFaultZoneId, 
_resourceNames.get(0),
+_partitionNames.get(0));
+
+Assert.assertEquals(context.getAssignmentForFaultZoneMap(), 
expectedFaultZoneMap);
+  }
+
+  @Test(expectedExceptions = HelixException.class, 
expectedExceptionsMessageRegExp = "Resource Resource1 already has a replica 
from partition Partition1 in fault zone testZone")
+  public void testAssignAlreadyExist() throws IOException {
 
 Review comment:
   testDuplicateAssign


This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
us...@infra.apache.org


With regards,
Apache Git Services


[GitHub] [helix] jiajunwang commented on a change in pull request #362: The WAGED rebalancer cluster model implementation

2019-08-02 Thread GitBox
jiajunwang commented on a change in pull request #362: The WAGED rebalancer 
cluster model implementation
URL: https://github.com/apache/helix/pull/362#discussion_r310278490
 
 

 ##
 File path: 
helix-core/src/test/java/org/apache/helix/controller/rebalancer/waged/model/TestAssignableReplica.java
 ##
 @@ -0,0 +1,100 @@
+package org.apache.helix.controller.rebalancer.waged.model;
+
+/*
+ * 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 org.apache.helix.model.ResourceConfig;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import java.io.IOException;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import static org.apache.helix.model.StateModelDefinition.TOP_STATE_PRIORITY;
+
+public class TestAssignableReplica {
+  String resourceName = "Resource";
+  String partitionNamePrefix = "partition";
+  String masterState = "Master";
+  int masterPriority = TOP_STATE_PRIORITY;
+  String slaveState = "Slave";
+  int slavePriority = 2;
+
+  @Test
+  public void testConstructRepliaWithResourceConfig() throws IOException {
+// Init assignable replication with a basic config object
+Map capacityDataMapResource1 = new HashMap<>();
+capacityDataMapResource1.put("item1", 3);
+capacityDataMapResource1.put("item2", 6);
+ResourceConfig testResourceConfigResource = new 
ResourceConfig(resourceName);
+testResourceConfigResource.setPartitionCapacityMap(
+Collections.singletonMap(ResourceConfig.DEFAULT_PARTITION_KEY, 
capacityDataMapResource1));
+
+String partitionName = partitionNamePrefix + 1;
+AssignableReplica replica =
+new AssignableReplica(testResourceConfigResource, partitionName, 
masterState,
+masterPriority);
+Assert.assertEquals(replica.getResourceName(), resourceName);
 
 Review comment:
   In that case, we will still need to list all the different parameters. 
Moreover, if anything new to check in different places, we need to split the 
method or check redundantly. So I prefer to keep the Asserts listed in the test 
case.


This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
us...@infra.apache.org


With regards,
Apache Git Services


[GitHub] [helix] jiajunwang commented on a change in pull request #362: The WAGED rebalancer cluster model implementation

2019-08-02 Thread GitBox
jiajunwang commented on a change in pull request #362: The WAGED rebalancer 
cluster model implementation
URL: https://github.com/apache/helix/pull/362#discussion_r310277680
 
 

 ##
 File path: 
helix-core/src/test/java/org/apache/helix/controller/rebalancer/waged/model/TestAssignableReplica.java
 ##
 @@ -0,0 +1,100 @@
+package org.apache.helix.controller.rebalancer.waged.model;
+
+/*
+ * 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 org.apache.helix.model.ResourceConfig;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import java.io.IOException;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import static org.apache.helix.model.StateModelDefinition.TOP_STATE_PRIORITY;
 
 Review comment:
   This is automatically done... I'm fine with both. Will change it.


This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
us...@infra.apache.org


With regards,
Apache Git Services


[GitHub] [helix] jiajunwang commented on a change in pull request #362: The WAGED rebalancer cluster model implementation

2019-08-02 Thread GitBox
jiajunwang commented on a change in pull request #362: The WAGED rebalancer 
cluster model implementation
URL: https://github.com/apache/helix/pull/362#discussion_r310277478
 
 

 ##
 File path: 
helix-core/src/test/java/org/apache/helix/controller/rebalancer/waged/model/TestAssignableNode.java
 ##
 @@ -0,0 +1,203 @@
+package org.apache.helix.controller.rebalancer.waged.model;
+
+/*
+ * 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 org.apache.helix.HelixException;
+import 
org.apache.helix.controller.dataproviders.ResourceControllerDataProvider;
+import org.apache.helix.integration.task.TaskTestBase;
+import org.apache.helix.model.BuiltInStateModelDefinitions;
+import org.apache.helix.model.ClusterConfig;
+import org.apache.helix.model.CurrentState;
+import org.apache.helix.model.InstanceConfig;
+import org.apache.helix.model.LiveInstance;
+import org.apache.helix.model.ResourceConfig;
+import org.mockito.Mockito;
+import org.testng.Assert;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import static org.mockito.Mockito.when;
+
+public class TestAssignableNode extends AbstractTestClusterModel {
+  @BeforeClass
+  public void initialize() {
+super.initialize();
+  }
+
+  @Test
+  public void testNormalUsage() throws IOException {
+ResourceControllerDataProvider testCache = setupClusterDataCache();
+Set assignmentSet = generateReplicas(testCache);
+
+// Test 1 - initialization
+
+Set expectedAssignmentSet1 = new 
HashSet<>(_partitionNames.subList(0, 2));
+Set expectedAssignmentSet2 = new 
HashSet<>(_partitionNames.subList(2, 4));
+Map> expectedAssignment = new HashMap<>();
+expectedAssignment.put("Resource1", expectedAssignmentSet1);
+expectedAssignment.put("Resource2", expectedAssignmentSet2);
+Map expectedCapacityMap = new HashMap<>();
+expectedCapacityMap.put("item1", 4);
+expectedCapacityMap.put("item2", 8);
+expectedCapacityMap.put("item3", 30);
+
+
+AssignableNode assignableNode = new AssignableNode(testCache, 
_testInstanceId, assignmentSet);
+
Assert.assertTrue(assignableNode.getCurrentAssignmentsMap().equals(expectedAssignment));
+Assert.assertEquals(assignableNode.getCurrentAssignmentCount(), 4);
+Assert.assertEquals(assignableNode.getHighestCapacityUtilization(), 16.0 / 
20.0, 0.005);
+
Assert.assertTrue(assignableNode.getMaxCapacity().equals(_capacityDataMap));
+Assert.assertEquals(assignableNode.getMaxPartition(), 5);
+Assert.assertEquals(assignableNode.getInstanceTags(), _testInstanceTags);
+Assert.assertEquals(assignableNode.getFaultZone(), _testFaultZoneId);
+
Assert.assertTrue(assignableNode.getDisabledPartitionsMap().equals(_disabledPartitionsMap));
+
Assert.assertTrue(assignableNode.getCurrentCapacity().equals(expectedCapacityMap));
+
+// Test 2 - reduce assignment
+AssignableReplica removingReplica =
+new 
AssignableReplica(testCache.getResourceConfig(_resourceNames.get(1)),
+_partitionNames.get(2), "MASTER", 1);
+
expectedAssignment.get(_resourceNames.get(1)).remove(_partitionNames.get(2));
+expectedCapacityMap.put("item1", 9);
+expectedCapacityMap.put("item2", 18);
+
+assignableNode.release(removingReplica);
+
+
Assert.assertTrue(assignableNode.getCurrentAssignmentsMap().equals(expectedAssignment));
+Assert.assertEquals(assignableNode.getCurrentAssignmentCount(), 3);
+Assert.assertEquals(assignableNode.getHighestCapacityUtilization(), 11.0 / 
20.0, 0.005);
+
Assert.assertTrue(assignableNode.getMaxCapacity().equals(_capacityDataMap));
+Assert.assertEquals(assignableNode.getMaxPartition(), 5);
+Assert.assertEquals(assignableNode.getInstanceTags(), _testInstanceTags);
+Assert.assertEquals(assignableNode.getFaultZone(), _testFaultZoneId);
+
Assert.assertTrue(assignableNode.getDisabledPartitionsMap().equals(_disabledPartitionsMap));
+

[GitHub] [helix] jiajunwang commented on a change in pull request #362: The WAGED rebalancer cluster model implementation

2019-08-02 Thread GitBox
jiajunwang commented on a change in pull request #362: The WAGED rebalancer 
cluster model implementation
URL: https://github.com/apache/helix/pull/362#discussion_r310277080
 
 

 ##
 File path: 
helix-core/src/test/java/org/apache/helix/controller/rebalancer/waged/model/TestAssignableNode.java
 ##
 @@ -0,0 +1,203 @@
+package org.apache.helix.controller.rebalancer.waged.model;
+
+/*
+ * 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 org.apache.helix.HelixException;
+import 
org.apache.helix.controller.dataproviders.ResourceControllerDataProvider;
+import org.apache.helix.integration.task.TaskTestBase;
+import org.apache.helix.model.BuiltInStateModelDefinitions;
+import org.apache.helix.model.ClusterConfig;
+import org.apache.helix.model.CurrentState;
+import org.apache.helix.model.InstanceConfig;
+import org.apache.helix.model.LiveInstance;
+import org.apache.helix.model.ResourceConfig;
+import org.mockito.Mockito;
+import org.testng.Assert;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import static org.mockito.Mockito.when;
+
+public class TestAssignableNode extends AbstractTestClusterModel {
+  @BeforeClass
+  public void initialize() {
+super.initialize();
+  }
+
+  @Test
+  public void testNormalUsage() throws IOException {
+ResourceControllerDataProvider testCache = setupClusterDataCache();
+Set assignmentSet = generateReplicas(testCache);
+
+// Test 1 - initialization
+
+Set expectedAssignmentSet1 = new 
HashSet<>(_partitionNames.subList(0, 2));
+Set expectedAssignmentSet2 = new 
HashSet<>(_partitionNames.subList(2, 4));
+Map> expectedAssignment = new HashMap<>();
+expectedAssignment.put("Resource1", expectedAssignmentSet1);
+expectedAssignment.put("Resource2", expectedAssignmentSet2);
+Map expectedCapacityMap = new HashMap<>();
+expectedCapacityMap.put("item1", 4);
+expectedCapacityMap.put("item2", 8);
+expectedCapacityMap.put("item3", 30);
+
+
+AssignableNode assignableNode = new AssignableNode(testCache, 
_testInstanceId, assignmentSet);
+
Assert.assertTrue(assignableNode.getCurrentAssignmentsMap().equals(expectedAssignment));
+Assert.assertEquals(assignableNode.getCurrentAssignmentCount(), 4);
+Assert.assertEquals(assignableNode.getHighestCapacityUtilization(), 16.0 / 
20.0, 0.005);
+
Assert.assertTrue(assignableNode.getMaxCapacity().equals(_capacityDataMap));
+Assert.assertEquals(assignableNode.getMaxPartition(), 5);
+Assert.assertEquals(assignableNode.getInstanceTags(), _testInstanceTags);
+Assert.assertEquals(assignableNode.getFaultZone(), _testFaultZoneId);
+
Assert.assertTrue(assignableNode.getDisabledPartitionsMap().equals(_disabledPartitionsMap));
+
Assert.assertTrue(assignableNode.getCurrentCapacity().equals(expectedCapacityMap));
+
+// Test 2 - reduce assignment
+AssignableReplica removingReplica =
+new 
AssignableReplica(testCache.getResourceConfig(_resourceNames.get(1)),
+_partitionNames.get(2), "MASTER", 1);
+
expectedAssignment.get(_resourceNames.get(1)).remove(_partitionNames.get(2));
+expectedCapacityMap.put("item1", 9);
+expectedCapacityMap.put("item2", 18);
+
+assignableNode.release(removingReplica);
+
+
Assert.assertTrue(assignableNode.getCurrentAssignmentsMap().equals(expectedAssignment));
+Assert.assertEquals(assignableNode.getCurrentAssignmentCount(), 3);
+Assert.assertEquals(assignableNode.getHighestCapacityUtilization(), 11.0 / 
20.0, 0.005);
+
Assert.assertTrue(assignableNode.getMaxCapacity().equals(_capacityDataMap));
+Assert.assertEquals(assignableNode.getMaxPartition(), 5);
+Assert.assertEquals(assignableNode.getInstanceTags(), _testInstanceTags);
+Assert.assertEquals(assignableNode.getFaultZone(), _testFaultZoneId);
+
Assert.assertTrue(assignableNode.getDisabledPartitionsMap().equals(_disabledPartitionsMap));
+

Missing 0.9.0.1 Helix release in maven repository

2019-08-02 Thread Xue Junkai
Hi Folks,

We are generating an Apache Helix release 0.9.0.1. Everything looks good
after we click the release in Repository Manager.

But we did not find the 0.9.0.1 release in maven repository until now.
Could you please help us figure it out why it is not showing up? It was
released yesterday 6pm.

Could that be maven only supports 3 level version?

Best,

Junkai


[GitHub] [helix] jiajunwang commented on a change in pull request #362: The WAGED rebalancer cluster model implementation

2019-08-02 Thread GitBox
jiajunwang commented on a change in pull request #362: The WAGED rebalancer 
cluster model implementation
URL: https://github.com/apache/helix/pull/362#discussion_r310276844
 
 

 ##
 File path: 
helix-core/src/test/java/org/apache/helix/controller/rebalancer/waged/model/TestAssignableNode.java
 ##
 @@ -0,0 +1,203 @@
+package org.apache.helix.controller.rebalancer.waged.model;
+
+/*
+ * 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 org.apache.helix.HelixException;
+import 
org.apache.helix.controller.dataproviders.ResourceControllerDataProvider;
+import org.apache.helix.integration.task.TaskTestBase;
+import org.apache.helix.model.BuiltInStateModelDefinitions;
+import org.apache.helix.model.ClusterConfig;
+import org.apache.helix.model.CurrentState;
+import org.apache.helix.model.InstanceConfig;
+import org.apache.helix.model.LiveInstance;
+import org.apache.helix.model.ResourceConfig;
+import org.mockito.Mockito;
+import org.testng.Assert;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import static org.mockito.Mockito.when;
+
+public class TestAssignableNode extends AbstractTestClusterModel {
+  @BeforeClass
+  public void initialize() {
+super.initialize();
+  }
+
+  @Test
+  public void testNormalUsage() throws IOException {
+ResourceControllerDataProvider testCache = setupClusterDataCache();
+Set assignmentSet = generateReplicas(testCache);
+
+// Test 1 - initialization
+
+Set expectedAssignmentSet1 = new 
HashSet<>(_partitionNames.subList(0, 2));
+Set expectedAssignmentSet2 = new 
HashSet<>(_partitionNames.subList(2, 4));
+Map> expectedAssignment = new HashMap<>();
+expectedAssignment.put("Resource1", expectedAssignmentSet1);
+expectedAssignment.put("Resource2", expectedAssignmentSet2);
+Map expectedCapacityMap = new HashMap<>();
+expectedCapacityMap.put("item1", 4);
+expectedCapacityMap.put("item2", 8);
+expectedCapacityMap.put("item3", 30);
+
+
+AssignableNode assignableNode = new AssignableNode(testCache, 
_testInstanceId, assignmentSet);
+
Assert.assertTrue(assignableNode.getCurrentAssignmentsMap().equals(expectedAssignment));
+Assert.assertEquals(assignableNode.getCurrentAssignmentCount(), 4);
+Assert.assertEquals(assignableNode.getHighestCapacityUtilization(), 16.0 / 
20.0, 0.005);
+
Assert.assertTrue(assignableNode.getMaxCapacity().equals(_capacityDataMap));
+Assert.assertEquals(assignableNode.getMaxPartition(), 5);
+Assert.assertEquals(assignableNode.getInstanceTags(), _testInstanceTags);
+Assert.assertEquals(assignableNode.getFaultZone(), _testFaultZoneId);
+
Assert.assertTrue(assignableNode.getDisabledPartitionsMap().equals(_disabledPartitionsMap));
+
Assert.assertTrue(assignableNode.getCurrentCapacity().equals(expectedCapacityMap));
+
+// Test 2 - reduce assignment
+AssignableReplica removingReplica =
+new 
AssignableReplica(testCache.getResourceConfig(_resourceNames.get(1)),
+_partitionNames.get(2), "MASTER", 1);
+
expectedAssignment.get(_resourceNames.get(1)).remove(_partitionNames.get(2));
+expectedCapacityMap.put("item1", 9);
+expectedCapacityMap.put("item2", 18);
+
+assignableNode.release(removingReplica);
+
+
Assert.assertTrue(assignableNode.getCurrentAssignmentsMap().equals(expectedAssignment));
+Assert.assertEquals(assignableNode.getCurrentAssignmentCount(), 3);
+Assert.assertEquals(assignableNode.getHighestCapacityUtilization(), 11.0 / 
20.0, 0.005);
+
Assert.assertTrue(assignableNode.getMaxCapacity().equals(_capacityDataMap));
+Assert.assertEquals(assignableNode.getMaxPartition(), 5);
+Assert.assertEquals(assignableNode.getInstanceTags(), _testInstanceTags);
+Assert.assertEquals(assignableNode.getFaultZone(), _testFaultZoneId);
+
Assert.assertTrue(assignableNode.getDisabledPartitionsMap().equals(_disabledPartitionsMap));
+

[GitHub] [helix] jiajunwang commented on a change in pull request #362: The WAGED rebalancer cluster model implementation

2019-08-02 Thread GitBox
jiajunwang commented on a change in pull request #362: The WAGED rebalancer 
cluster model implementation
URL: https://github.com/apache/helix/pull/362#discussion_r310249111
 
 

 ##
 File path: 
helix-core/src/test/java/org/apache/helix/controller/rebalancer/waged/model/AbstractTestClusterModel.java
 ##
 @@ -0,0 +1,161 @@
+package org.apache.helix.controller.rebalancer.waged.model;
+
+/*
+ * 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 
org.apache.helix.controller.dataproviders.ResourceControllerDataProvider;
+import org.apache.helix.model.BuiltInStateModelDefinitions;
+import org.apache.helix.model.ClusterConfig;
+import org.apache.helix.model.CurrentState;
+import org.apache.helix.model.InstanceConfig;
+import org.apache.helix.model.LiveInstance;
+import org.apache.helix.model.ResourceConfig;
+import org.mockito.Mockito;
+import org.testng.annotations.BeforeClass;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import static org.mockito.Mockito.when;
+
+public abstract class AbstractTestClusterModel {
+  protected String _testInstanceId;
+  protected List _resourceNames;
+  protected List _partitionNames;
+  protected Map _capacityDataMap;
+  protected Map> _disabledPartitionsMap;
+  protected List _testInstanceTags;
+  protected String _testFaultZoneId;
+
+  @BeforeClass
+  public void initialize() {
+_testInstanceId = "testInstanceId";
+_resourceNames = new ArrayList<>();
+_resourceNames.add("Resource1");
+_resourceNames.add("Resource2");
+_partitionNames = new ArrayList<>();
+_partitionNames.add("Partition1");
+_partitionNames.add("Partition2");
+_partitionNames.add("Partition3");
+_partitionNames.add("Partition4");
+_capacityDataMap = new HashMap<>();
+_capacityDataMap.put("item1", 20);
+_capacityDataMap.put("item2", 40);
+_capacityDataMap.put("item3", 30);
+List disabledPartitions = new ArrayList<>();
+disabledPartitions.add("TestPartition");
+_disabledPartitionsMap = new HashMap<>();
+_disabledPartitionsMap.put("TestResource", disabledPartitions);
+_testInstanceTags = new ArrayList<>();
+_testInstanceTags.add("TestTag");
+_testFaultZoneId = "testZone";
+  }
+
+  protected ResourceControllerDataProvider setupClusterDataCache() throws 
IOException {
 
 Review comment:
   Sure, make sense.


This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
us...@infra.apache.org


With regards,
Apache Git Services


[GitHub] [helix] jiajunwang commented on a change in pull request #362: The WAGED rebalancer cluster model implementation

2019-08-02 Thread GitBox
jiajunwang commented on a change in pull request #362: The WAGED rebalancer 
cluster model implementation
URL: https://github.com/apache/helix/pull/362#discussion_r310248906
 
 

 ##
 File path: 
helix-core/src/main/java/org/apache/helix/controller/rebalancer/waged/model/ClusterModel.java
 ##
 @@ -19,9 +19,131 @@
  * under the License.
  */
 
+import org.apache.helix.HelixException;
+import org.apache.helix.model.IdealState;
+
+import java.util.Collections;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
+
 /**
- * A placeholder before we have the implementation.
- *
  * This class wraps the required input for the rebalance algorithm.
  */
-public class ClusterModel { }
+public class ClusterModel {
+  private final ClusterContext _clusterContext;
+  // Map to track all the assignable replications. >
+  private final Map> _assignableReplicas;
+  // The index to find the replication information with a certain state. 
>
+  // Note that the identical replicas are dedupe in the index.
+  private final Map> 
_assignableReplicaIndex;
+  private final Map _assignableNodeMap;
+
+  // Records about the previous assignment
+  private final Map _baselineAssignment;
+  private final Map _bestPossibleAssignment;
+
+  /**
+   * @param clusterContext The initialized cluster context.
+   * @param assignableReplicas The replications to be assigned.
+   *   Note that the replicas in this list shall 
not be included while initializing the context and assignable nodes.
+   * @param assignableNodesThe active instances.
+   * @param baselineAssignment The recorded baseline assignment.
+   * @param bestPossibleAssignment The current best possible assignment.
+   */
+  ClusterModel(ClusterContext clusterContext, Set 
assignableReplicas,
+  Set assignableNodes, Map 
baselineAssignment,
+  Map bestPossibleAssignment) {
+_clusterContext = clusterContext;
+
+// Save all the to be assigned replication
+_assignableReplicas = assignableReplicas.stream()
+.collect(Collectors.groupingBy(AssignableReplica::getResourceName, 
Collectors.toSet()));
+
+// Index all the replicas to be assigned. Dedup the replica if two 
instances have the same resource/partition/state
+_assignableReplicaIndex = assignableReplicas.stream().collect(Collectors
+.groupingBy(AssignableReplica::getResourceName, Collectors
+.toMap(AssignableReplica::toString, replica -> replica,
+(oldValue, newValue) -> oldValue)));
+
+_assignableNodeMap = assignableNodes.stream()
+.collect(Collectors.toMap(AssignableNode::getInstanceName, node -> 
node));
+
+_baselineAssignment = baselineAssignment;
+_bestPossibleAssignment = bestPossibleAssignment;
+  }
+
+  public ClusterContext getContext() {
+return _clusterContext;
+  }
+
+  public Map getAssignableNodes() {
+return _assignableNodeMap;
+  }
+
+  public Map> getAssignableReplicas() {
+return _assignableReplicas;
+  }
+
+  public Map getBaseline() {
+return _baselineAssignment;
+  }
+
+  public Map getBestPossibleAssignment() {
+return _bestPossibleAssignment;
+  }
+
+  /**
+   * Propose the assignment to the cluster model.
+   *
+   * @param resourceName
+   * @param partitionName
+   * @param state
+   * @param instanceName
+   */
+  public void assign(String resourceName, String partitionName, String state, 
String instanceName) {
+AssignableNode node = locateAssignableNode(instanceName);
+AssignableReplica replica = locateAssignableReplica(resourceName, 
partitionName, state);
+
+node.assign(replica);
+_clusterContext.addPartitionToFaultZone(node.getFaultZone(), resourceName, 
partitionName);
+  }
+
+  /**
+   * Revert the proposed assignment from the cluster model.
+   *
+   * @param resourceName
+   * @param partitionName
+   * @param state
+   * @param instanceName
+   */
+  public void release(String resourceName, String partitionName, String state,
+  String instanceName) {
+AssignableNode node = locateAssignableNode(instanceName);
+AssignableReplica replica = locateAssignableReplica(resourceName, 
partitionName, state);
+
+node.release(replica);
+_clusterContext.removePartitionFromFaultZone(node.getFaultZone(), 
resourceName, partitionName);
+  }
+
+  private AssignableNode locateAssignableNode(String instanceName) {
+AssignableNode node = _assignableNodeMap.get(instanceName);
+if (node == null) {
+  throw new HelixException("Cannot find the instance: " + instanceName);
 
 Review comment:
   This is a public interface. If anyone calls it in a wrong way, we'd better 
have a HelixException instead of NPE.


This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, 

[GitHub] [helix] jiajunwang commented on a change in pull request #362: The WAGED rebalancer cluster model implementation

2019-08-02 Thread GitBox
jiajunwang commented on a change in pull request #362: The WAGED rebalancer 
cluster model implementation
URL: https://github.com/apache/helix/pull/362#discussion_r310246676
 
 

 ##
 File path: 
helix-core/src/main/java/org/apache/helix/controller/rebalancer/waged/model/ClusterModel.java
 ##
 @@ -19,9 +19,131 @@
  * under the License.
  */
 
+import org.apache.helix.HelixException;
+import org.apache.helix.model.IdealState;
+
+import java.util.Collections;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
+
 /**
- * A placeholder before we have the implementation.
- *
  * This class wraps the required input for the rebalance algorithm.
  */
-public class ClusterModel { }
+public class ClusterModel {
+  private final ClusterContext _clusterContext;
+  // Map to track all the assignable replications. >
+  private final Map> _assignableReplicas;
+  // The index to find the replication information with a certain state. 
>
+  // Note that the identical replicas are dedupe in the index.
 
 Review comment:
   Good catch


This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
us...@infra.apache.org


With regards,
Apache Git Services


[GitHub] [helix] jiajunwang commented on a change in pull request #362: The WAGED rebalancer cluster model implementation

2019-08-02 Thread GitBox
jiajunwang commented on a change in pull request #362: The WAGED rebalancer 
cluster model implementation
URL: https://github.com/apache/helix/pull/362#discussion_r310245795
 
 

 ##
 File path: 
helix-core/src/main/java/org/apache/helix/controller/rebalancer/waged/model/AssignableReplica.java
 ##
 @@ -19,9 +19,121 @@
  * under the License.
  */
 
+import org.apache.helix.model.ResourceConfig;
+import org.apache.helix.model.StateModelDefinition;
+
+import java.io.IOException;
+import java.util.Map;
+
 /**
- * A placeholder before we have the implementation.
- *
  * This class represents a partition replication that needs to be allocated.
  */
-public class AssignableReplica { }
+public class AssignableReplica implements Comparable {
+  private final String _partitionName;
+  private final String _resourceName;
+  private final String _resourceInstanceGroupTag;
+  private final int _resourceMaxPartitionsPerInstance;
+  private final Map _capacityUsage;
+  // The priority of the replica's state
+  private final int _statePriority;
+  // The state of the replica
+  private final String _replicaState;
+
+  /**
+   * @param resourceConfig The resource config for the resource which contains 
the replication.
+   * @param partitionName  The replication's partition name.
+   * @param replicaState   The state of the replication.
+   * @param statePriority  The priority of the replication's state.
+   */
+  AssignableReplica(ResourceConfig resourceConfig, String partitionName, 
String replicaState,
+  int statePriority) {
+_partitionName = partitionName;
+_replicaState = replicaState;
+_statePriority = statePriority;
+_resourceName = resourceConfig.getResourceName();
+_capacityUsage = fetchCapacityUsage(partitionName, resourceConfig);
 
 Review comment:
   Even the constructor of Assignable Replica is not public. There is no need 
we make the construction methods public. For now, I think it is overdesigned to 
use builder pattern here.
   
   We can revisit here if we are going to construct a replica object somewhere 
else.


This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
us...@infra.apache.org


With regards,
Apache Git Services


[GitHub] [helix] jiajunwang commented on a change in pull request #362: The WAGED rebalancer cluster model implementation

2019-08-02 Thread GitBox
jiajunwang commented on a change in pull request #362: The WAGED rebalancer 
cluster model implementation
URL: https://github.com/apache/helix/pull/362#discussion_r310244594
 
 

 ##
 File path: 
helix-core/src/test/java/org/apache/helix/controller/rebalancer/waged/model/AbstractTestClusterModel.java
 ##
 @@ -0,0 +1,161 @@
+package org.apache.helix.controller.rebalancer.waged.model;
+
+/*
+ * 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 
org.apache.helix.controller.dataproviders.ResourceControllerDataProvider;
+import org.apache.helix.model.BuiltInStateModelDefinitions;
+import org.apache.helix.model.ClusterConfig;
+import org.apache.helix.model.CurrentState;
+import org.apache.helix.model.InstanceConfig;
+import org.apache.helix.model.LiveInstance;
+import org.apache.helix.model.ResourceConfig;
+import org.mockito.Mockito;
+import org.testng.annotations.BeforeClass;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import static org.mockito.Mockito.when;
+
+public abstract class AbstractTestClusterModel {
+  protected String _testInstanceId;
+  protected List _resourceNames;
+  protected List _partitionNames;
+  protected Map _capacityDataMap;
+  protected Map> _disabledPartitionsMap;
+  protected List _testInstanceTags;
+  protected String _testFaultZoneId;
+
+  @BeforeClass
+  public void initialize() {
+_testInstanceId = "testInstanceId";
+_resourceNames = new ArrayList<>();
+_resourceNames.add("Resource1");
+_resourceNames.add("Resource2");
+_partitionNames = new ArrayList<>();
+_partitionNames.add("Partition1");
+_partitionNames.add("Partition2");
+_partitionNames.add("Partition3");
+_partitionNames.add("Partition4");
+_capacityDataMap = new HashMap<>();
+_capacityDataMap.put("item1", 20);
+_capacityDataMap.put("item2", 40);
+_capacityDataMap.put("item3", 30);
+List disabledPartitions = new ArrayList<>();
+disabledPartitions.add("TestPartition");
+_disabledPartitionsMap = new HashMap<>();
 
 Review comment:
   As comments above, I don't want to make this list immutable.


This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
us...@infra.apache.org


With regards,
Apache Git Services


[GitHub] [helix] jiajunwang commented on a change in pull request #362: The WAGED rebalancer cluster model implementation

2019-08-02 Thread GitBox
jiajunwang commented on a change in pull request #362: The WAGED rebalancer 
cluster model implementation
URL: https://github.com/apache/helix/pull/362#discussion_r310244369
 
 

 ##
 File path: 
helix-core/src/test/java/org/apache/helix/controller/rebalancer/waged/model/AbstractTestClusterModel.java
 ##
 @@ -0,0 +1,161 @@
+package org.apache.helix.controller.rebalancer.waged.model;
+
+/*
+ * 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 
org.apache.helix.controller.dataproviders.ResourceControllerDataProvider;
+import org.apache.helix.model.BuiltInStateModelDefinitions;
+import org.apache.helix.model.ClusterConfig;
+import org.apache.helix.model.CurrentState;
+import org.apache.helix.model.InstanceConfig;
+import org.apache.helix.model.LiveInstance;
+import org.apache.helix.model.ResourceConfig;
+import org.mockito.Mockito;
+import org.testng.annotations.BeforeClass;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import static org.mockito.Mockito.when;
+
+public abstract class AbstractTestClusterModel {
+  protected String _testInstanceId;
+  protected List _resourceNames;
+  protected List _partitionNames;
+  protected Map _capacityDataMap;
+  protected Map> _disabledPartitionsMap;
+  protected List _testInstanceTags;
+  protected String _testFaultZoneId;
+
+  @BeforeClass
+  public void initialize() {
+_testInstanceId = "testInstanceId";
+_resourceNames = new ArrayList<>();
 
 Review comment:
   This is a test class. The abstract class might be used by the child in any 
way. So if they want to add more resources to the list, it is fine.


This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
us...@infra.apache.org


With regards,
Apache Git Services


[GitHub] [helix] narendly commented on a change in pull request #369: Add the workaround fix for assigning partitions when instance weight …

2019-08-02 Thread GitBox
narendly commented on a change in pull request #369: Add the workaround fix for 
assigning partitions when instance weight …
URL: https://github.com/apache/helix/pull/369#discussion_r310237287
 
 

 ##
 File path: 
helix-core/src/test/java/org/apache/helix/controller/rebalancer/strategy/crushMapping/TestCardDealingAdjustmentAlgorithmV2.java
 ##
 @@ -0,0 +1,328 @@
+package org.apache.helix.controller.rebalancer.strategy.crushMapping;
+
+/*
+ * 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 com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Sets;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import org.apache.helix.controller.rebalancer.topology.InstanceNode;
+import org.apache.helix.controller.rebalancer.topology.Node;
+import org.apache.helix.controller.rebalancer.topology.Topology;
+import org.testng.Assert;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import static org.mockito.Mockito.*;
+
+
+public class TestCardDealingAdjustmentAlgorithmV2 {
+  private Topology _topology;
+  private int[][] _defaultFaultZones = new int[][]{{1, 2, 3}, // zone0: i1, 
i2, i3
+  {4, 5, 6}, // zone1: i4, i5, i6
+  {7, 8, 9}  // zone0: i7, i8, i9
+  };
+
+  @BeforeClass
+  public void setUpTopology() {
+_topology = mock(Topology.class);
+
when(_topology.getFaultZones()).thenReturn(createFaultZones(_defaultFaultZones));
+  }
+
+  @Test(description = "Verify a few properties after algorithm instance is 
created")
+  public void testAlgorithmConstructor() {
+CardDealingAdjustmentAlgorithmV2 algorithm =
+new CardDealingAdjustmentAlgorithmV2(_topology, 3, 
CardDealingAdjustmentAlgorithmV2.Mode.EVENNESS);
+Map instanceWeights = algorithm.getInstanceWeight();
+// verify weight is set correctly
+for (Map.Entry entry : instanceWeights.entrySet()) {
+  if (entry.getKey().getId() != entry.getValue()) {
+Assert.fail(String.format("%s %s should have weight of %s", 
entry.getKey().getName(), entry.getKey().getId(),
+entry.getValue()));
+  }
+}
+Map faultZoneWeights = algorithm.getFaultZoneWeight();
+Map> faultZonePartationMap = 
algorithm.getFaultZonePartitionMap();
 
 Review comment:
   Partation -> Partition


This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
us...@infra.apache.org


With regards,
Apache Git Services


[GitHub] [helix] narendly commented on a change in pull request #369: Add the workaround fix for assigning partitions when instance weight …

2019-08-02 Thread GitBox
narendly commented on a change in pull request #369: Add the workaround fix for 
assigning partitions when instance weight …
URL: https://github.com/apache/helix/pull/369#discussion_r310238349
 
 

 ##
 File path: 
helix-core/src/test/java/org/apache/helix/controller/rebalancer/strategy/crushMapping/TestCardDealingAdjustmentAlgorithmV2.java
 ##
 @@ -0,0 +1,328 @@
+package org.apache.helix.controller.rebalancer.strategy.crushMapping;
+
+/*
+ * 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 com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Sets;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import org.apache.helix.controller.rebalancer.topology.InstanceNode;
+import org.apache.helix.controller.rebalancer.topology.Node;
+import org.apache.helix.controller.rebalancer.topology.Topology;
+import org.testng.Assert;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import static org.mockito.Mockito.*;
+
+
+public class TestCardDealingAdjustmentAlgorithmV2 {
+  private Topology _topology;
+  private int[][] _defaultFaultZones = new int[][]{{1, 2, 3}, // zone0: i1, 
i2, i3
+  {4, 5, 6}, // zone1: i4, i5, i6
+  {7, 8, 9}  // zone0: i7, i8, i9
+  };
+
+  @BeforeClass
+  public void setUpTopology() {
+_topology = mock(Topology.class);
+
when(_topology.getFaultZones()).thenReturn(createFaultZones(_defaultFaultZones));
+  }
+
+  @Test(description = "Verify a few properties after algorithm instance is 
created")
+  public void testAlgorithmConstructor() {
+CardDealingAdjustmentAlgorithmV2 algorithm =
+new CardDealingAdjustmentAlgorithmV2(_topology, 3, 
CardDealingAdjustmentAlgorithmV2.Mode.EVENNESS);
+Map instanceWeights = algorithm.getInstanceWeight();
+// verify weight is set correctly
+for (Map.Entry entry : instanceWeights.entrySet()) {
+  if (entry.getKey().getId() != entry.getValue()) {
+Assert.fail(String.format("%s %s should have weight of %s", 
entry.getKey().getName(), entry.getKey().getId(),
+entry.getValue()));
+  }
+}
+Map faultZoneWeights = algorithm.getFaultZoneWeight();
+Map> faultZonePartationMap = 
algorithm.getFaultZonePartitionMap();
+Set faultZones = faultZoneWeights.keySet();
+
+Assert.assertEquals(faultZoneWeights.size(), 3);
+Assert.assertEquals(faultZonePartationMap.keySet(), faultZones);
+
+long sum = 0;
+for (long weight : faultZoneWeights.values()) {
+  sum += weight;
+}
+// verify total weight is computed correct
+if (sum != algorithm.getTotalWeight()) {
 
 Review comment:
   Nit: also could do Assert.assertEquals(condition, error msg). One liner. I'm 
fine with the way it is.


This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
us...@infra.apache.org


With regards,
Apache Git Services


[GitHub] [helix] narendly commented on a change in pull request #369: Add the workaround fix for assigning partitions when instance weight …

2019-08-02 Thread GitBox
narendly commented on a change in pull request #369: Add the workaround fix for 
assigning partitions when instance weight …
URL: https://github.com/apache/helix/pull/369#discussion_r310239674
 
 

 ##
 File path: 
helix-core/src/test/java/org/apache/helix/controller/rebalancer/strategy/crushMapping/TestCardDealingAdjustmentAlgorithmV2.java
 ##
 @@ -0,0 +1,328 @@
+package org.apache.helix.controller.rebalancer.strategy.crushMapping;
+
+/*
+ * 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 com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Sets;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import org.apache.helix.controller.rebalancer.topology.InstanceNode;
+import org.apache.helix.controller.rebalancer.topology.Node;
+import org.apache.helix.controller.rebalancer.topology.Topology;
+import org.testng.Assert;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import static org.mockito.Mockito.*;
+
+
+public class TestCardDealingAdjustmentAlgorithmV2 {
+  private Topology _topology;
+  private int[][] _defaultFaultZones = new int[][]{{1, 2, 3}, // zone0: i1, 
i2, i3
+  {4, 5, 6}, // zone1: i4, i5, i6
+  {7, 8, 9}  // zone0: i7, i8, i9
+  };
+
+  @BeforeClass
+  public void setUpTopology() {
+_topology = mock(Topology.class);
+
when(_topology.getFaultZones()).thenReturn(createFaultZones(_defaultFaultZones));
+  }
+
+  @Test(description = "Verify a few properties after algorithm instance is 
created")
+  public void testAlgorithmConstructor() {
+CardDealingAdjustmentAlgorithmV2 algorithm =
+new CardDealingAdjustmentAlgorithmV2(_topology, 3, 
CardDealingAdjustmentAlgorithmV2.Mode.EVENNESS);
+Map instanceWeights = algorithm.getInstanceWeight();
+// verify weight is set correctly
+for (Map.Entry entry : instanceWeights.entrySet()) {
+  if (entry.getKey().getId() != entry.getValue()) {
+Assert.fail(String.format("%s %s should have weight of %s", 
entry.getKey().getName(), entry.getKey().getId(),
+entry.getValue()));
+  }
+}
+Map faultZoneWeights = algorithm.getFaultZoneWeight();
+Map> faultZonePartationMap = 
algorithm.getFaultZonePartitionMap();
+Set faultZones = faultZoneWeights.keySet();
+
+Assert.assertEquals(faultZoneWeights.size(), 3);
+Assert.assertEquals(faultZonePartationMap.keySet(), faultZones);
+
+long sum = 0;
+for (long weight : faultZoneWeights.values()) {
+  sum += weight;
+}
+// verify total weight is computed correct
+if (sum != algorithm.getTotalWeight()) {
+  Assert.fail(String.format("total weight %s != total weight of zones %s", 
algorithm.getTotalWeight(), sum));
+}
+Map instanceFaultZone = algorithm.getInstanceFaultZone();
+Assert.assertEquals(instanceFaultZone.size(), 9);
+
+// verify zone mapping is correct
+for (Node zone : faultZones) {
+  long zoneId = zone.getId();
+  Set instanceIds = ImmutableSet.of(3 * zoneId + 1L, 3 * zoneId + 
2L, 3 * zoneId + 3L);
+  List instanceNodes = zone.getChildren();
+  Assert.assertEquals(instanceNodes.size(), 3);
+  Set actualInstanceIds = new HashSet<>();
+  for (Node node : instanceNodes) {
+actualInstanceIds.add(node.getId());
+  }
+  Assert.assertEquals(actualInstanceIds, instanceIds);
+}
+  }
+
+  @DataProvider
+  public static Object[][] stableComputingVerification() {
+return new Object[][]{
+// replica, repeatTimes, seed, true: evenness false: less movement
+{1, 10, 0, true}, {2, 10, 10, true}, {3, 10, 100, true}, {1, 10, 0, 
true}, {2, 10, 10, true},
+{3, 10, 100, true}, {1, 10, 0, true}, {2, 10, 10, true}, {3, 10, 100, 
true}, {1, 10, 0, false},
+{2, 10, 10, false}, {3, 10, 100, false}, {1, 10, 0, false}, {2, 10, 
10, false}, {3, 10, 100, false},
+{1, 10, 0, false}, {2, 10, 10, false}, {3, 10, 100, false}};
+  }
+
+  @Test(description = "Compute mapping multiple times, the mapping of 

[GitHub] [helix] narendly commented on a change in pull request #369: Add the workaround fix for assigning partitions when instance weight …

2019-08-02 Thread GitBox
narendly commented on a change in pull request #369: Add the workaround fix for 
assigning partitions when instance weight …
URL: https://github.com/apache/helix/pull/369#discussion_r310236475
 
 

 ##
 File path: 
helix-core/src/test/java/org/apache/helix/controller/rebalancer/strategy/crushMapping/TestCardDealingAdjustmentAlgorithmV2.java
 ##
 @@ -0,0 +1,328 @@
+package org.apache.helix.controller.rebalancer.strategy.crushMapping;
+
+/*
+ * 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 com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Sets;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import org.apache.helix.controller.rebalancer.topology.InstanceNode;
+import org.apache.helix.controller.rebalancer.topology.Node;
+import org.apache.helix.controller.rebalancer.topology.Topology;
+import org.testng.Assert;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import static org.mockito.Mockito.*;
+
+
+public class TestCardDealingAdjustmentAlgorithmV2 {
+  private Topology _topology;
+  private int[][] _defaultFaultZones = new int[][]{{1, 2, 3}, // zone0: i1, 
i2, i3
+  {4, 5, 6}, // zone1: i4, i5, i6
+  {7, 8, 9}  // zone0: i7, i8, i9
+  };
+
+  @BeforeClass
+  public void setUpTopology() {
+_topology = mock(Topology.class);
+
when(_topology.getFaultZones()).thenReturn(createFaultZones(_defaultFaultZones));
+  }
+
+  @Test(description = "Verify a few properties after algorithm instance is 
created")
+  public void testAlgorithmConstructor() {
+CardDealingAdjustmentAlgorithmV2 algorithm =
+new CardDealingAdjustmentAlgorithmV2(_topology, 3, 
CardDealingAdjustmentAlgorithmV2.Mode.EVENNESS);
+Map instanceWeights = algorithm.getInstanceWeight();
+// verify weight is set correctly
+for (Map.Entry entry : instanceWeights.entrySet()) {
+  if (entry.getKey().getId() != entry.getValue()) {
+Assert.fail(String.format("%s %s should have weight of %s", 
entry.getKey().getName(), entry.getKey().getId(),
+entry.getValue()));
+  }
+}
+Map faultZoneWeights = algorithm.getFaultZoneWeight();
+Map> faultZonePartationMap = 
algorithm.getFaultZonePartitionMap();
+Set faultZones = faultZoneWeights.keySet();
+
+Assert.assertEquals(faultZoneWeights.size(), 3);
+Assert.assertEquals(faultZonePartationMap.keySet(), faultZones);
+
+long sum = 0;
+for (long weight : faultZoneWeights.values()) {
+  sum += weight;
+}
+// verify total weight is computed correct
+if (sum != algorithm.getTotalWeight()) {
+  Assert.fail(String.format("total weight %s != total weight of zones %s", 
algorithm.getTotalWeight(), sum));
+}
+Map instanceFaultZone = algorithm.getInstanceFaultZone();
+Assert.assertEquals(instanceFaultZone.size(), 9);
+
+// verify zone mapping is correct
+for (Node zone : faultZones) {
+  long zoneId = zone.getId();
+  Set instanceIds = ImmutableSet.of(3 * zoneId + 1L, 3 * zoneId + 
2L, 3 * zoneId + 3L);
+  List instanceNodes = zone.getChildren();
+  Assert.assertEquals(instanceNodes.size(), 3);
+  Set actualInstanceIds = new HashSet<>();
+  for (Node node : instanceNodes) {
+actualInstanceIds.add(node.getId());
+  }
+  Assert.assertEquals(actualInstanceIds, instanceIds);
+}
+  }
+
+  @DataProvider
+  public static Object[][] stableComputingVerification() {
+return new Object[][]{
+// replica, repeatTimes, seed, true: evenness false: less movement
+{1, 10, 0, true}, {2, 10, 10, true}, {3, 10, 100, true}, {1, 10, 0, 
true}, {2, 10, 10, true},
+{3, 10, 100, true}, {1, 10, 0, true}, {2, 10, 10, true}, {3, 10, 100, 
true}, {1, 10, 0, false},
+{2, 10, 10, false}, {3, 10, 100, false}, {1, 10, 0, false}, {2, 10, 
10, false}, {3, 10, 100, false},
+{1, 10, 0, false}, {2, 10, 10, false}, {3, 10, 100, false}};
+  }
+
+  @Test(description = "Compute mapping multiple times, the mapping of 

[GitHub] [helix] narendly commented on a change in pull request #369: Add the workaround fix for assigning partitions when instance weight …

2019-08-02 Thread GitBox
narendly commented on a change in pull request #369: Add the workaround fix for 
assigning partitions when instance weight …
URL: https://github.com/apache/helix/pull/369#discussion_r310237911
 
 

 ##
 File path: 
helix-core/src/test/java/org/apache/helix/controller/rebalancer/strategy/crushMapping/TestCardDealingAdjustmentAlgorithmV2.java
 ##
 @@ -0,0 +1,328 @@
+package org.apache.helix.controller.rebalancer.strategy.crushMapping;
+
+/*
+ * 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 com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Sets;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import org.apache.helix.controller.rebalancer.topology.InstanceNode;
+import org.apache.helix.controller.rebalancer.topology.Node;
+import org.apache.helix.controller.rebalancer.topology.Topology;
+import org.testng.Assert;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import static org.mockito.Mockito.*;
+
+
+public class TestCardDealingAdjustmentAlgorithmV2 {
+  private Topology _topology;
+  private int[][] _defaultFaultZones = new int[][]{{1, 2, 3}, // zone0: i1, 
i2, i3
+  {4, 5, 6}, // zone1: i4, i5, i6
+  {7, 8, 9}  // zone0: i7, i8, i9
+  };
+
+  @BeforeClass
+  public void setUpTopology() {
+_topology = mock(Topology.class);
+
when(_topology.getFaultZones()).thenReturn(createFaultZones(_defaultFaultZones));
+  }
+
+  @Test(description = "Verify a few properties after algorithm instance is 
created")
+  public void testAlgorithmConstructor() {
+CardDealingAdjustmentAlgorithmV2 algorithm =
+new CardDealingAdjustmentAlgorithmV2(_topology, 3, 
CardDealingAdjustmentAlgorithmV2.Mode.EVENNESS);
+Map instanceWeights = algorithm.getInstanceWeight();
+// verify weight is set correctly
+for (Map.Entry entry : instanceWeights.entrySet()) {
+  if (entry.getKey().getId() != entry.getValue()) {
+Assert.fail(String.format("%s %s should have weight of %s", 
entry.getKey().getName(), entry.getKey().getId(),
+entry.getValue()));
+  }
+}
+Map faultZoneWeights = algorithm.getFaultZoneWeight();
+Map> faultZonePartationMap = 
algorithm.getFaultZonePartitionMap();
+Set faultZones = faultZoneWeights.keySet();
+
+Assert.assertEquals(faultZoneWeights.size(), 3);
 
 Review comment:
   This 3 is a magic number, so let's make it `NUM_FAULT_ZONES` and make it a 
constant.


This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
us...@infra.apache.org


With regards,
Apache Git Services


[GitHub] [helix] narendly commented on a change in pull request #369: Add the workaround fix for assigning partitions when instance weight …

2019-08-02 Thread GitBox
narendly commented on a change in pull request #369: Add the workaround fix for 
assigning partitions when instance weight …
URL: https://github.com/apache/helix/pull/369#discussion_r310239447
 
 

 ##
 File path: 
helix-core/src/test/java/org/apache/helix/controller/rebalancer/strategy/crushMapping/TestCardDealingAdjustmentAlgorithmV2.java
 ##
 @@ -0,0 +1,328 @@
+package org.apache.helix.controller.rebalancer.strategy.crushMapping;
+
+/*
+ * 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 com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Sets;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import org.apache.helix.controller.rebalancer.topology.InstanceNode;
+import org.apache.helix.controller.rebalancer.topology.Node;
+import org.apache.helix.controller.rebalancer.topology.Topology;
+import org.testng.Assert;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import static org.mockito.Mockito.*;
+
+
+public class TestCardDealingAdjustmentAlgorithmV2 {
+  private Topology _topology;
+  private int[][] _defaultFaultZones = new int[][]{{1, 2, 3}, // zone0: i1, 
i2, i3
+  {4, 5, 6}, // zone1: i4, i5, i6
+  {7, 8, 9}  // zone0: i7, i8, i9
+  };
+
+  @BeforeClass
+  public void setUpTopology() {
+_topology = mock(Topology.class);
+
when(_topology.getFaultZones()).thenReturn(createFaultZones(_defaultFaultZones));
+  }
+
+  @Test(description = "Verify a few properties after algorithm instance is 
created")
+  public void testAlgorithmConstructor() {
+CardDealingAdjustmentAlgorithmV2 algorithm =
+new CardDealingAdjustmentAlgorithmV2(_topology, 3, 
CardDealingAdjustmentAlgorithmV2.Mode.EVENNESS);
+Map instanceWeights = algorithm.getInstanceWeight();
+// verify weight is set correctly
+for (Map.Entry entry : instanceWeights.entrySet()) {
+  if (entry.getKey().getId() != entry.getValue()) {
+Assert.fail(String.format("%s %s should have weight of %s", 
entry.getKey().getName(), entry.getKey().getId(),
+entry.getValue()));
+  }
+}
+Map faultZoneWeights = algorithm.getFaultZoneWeight();
+Map> faultZonePartationMap = 
algorithm.getFaultZonePartitionMap();
+Set faultZones = faultZoneWeights.keySet();
+
+Assert.assertEquals(faultZoneWeights.size(), 3);
+Assert.assertEquals(faultZonePartationMap.keySet(), faultZones);
+
+long sum = 0;
+for (long weight : faultZoneWeights.values()) {
+  sum += weight;
+}
+// verify total weight is computed correct
+if (sum != algorithm.getTotalWeight()) {
+  Assert.fail(String.format("total weight %s != total weight of zones %s", 
algorithm.getTotalWeight(), sum));
+}
+Map instanceFaultZone = algorithm.getInstanceFaultZone();
+Assert.assertEquals(instanceFaultZone.size(), 9);
+
+// verify zone mapping is correct
+for (Node zone : faultZones) {
+  long zoneId = zone.getId();
+  Set instanceIds = ImmutableSet.of(3 * zoneId + 1L, 3 * zoneId + 
2L, 3 * zoneId + 3L);
+  List instanceNodes = zone.getChildren();
+  Assert.assertEquals(instanceNodes.size(), 3);
 
 Review comment:
   Magic number -> constant


This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
us...@infra.apache.org


With regards,
Apache Git Services


[GitHub] [helix] narendly commented on a change in pull request #369: Add the workaround fix for assigning partitions when instance weight …

2019-08-02 Thread GitBox
narendly commented on a change in pull request #369: Add the workaround fix for 
assigning partitions when instance weight …
URL: https://github.com/apache/helix/pull/369#discussion_r310239990
 
 

 ##
 File path: 
helix-core/src/test/java/org/apache/helix/controller/rebalancer/strategy/crushMapping/TestCardDealingAdjustmentAlgorithmV2.java
 ##
 @@ -0,0 +1,328 @@
+package org.apache.helix.controller.rebalancer.strategy.crushMapping;
+
+/*
+ * 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 com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Sets;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import org.apache.helix.controller.rebalancer.topology.InstanceNode;
+import org.apache.helix.controller.rebalancer.topology.Node;
+import org.apache.helix.controller.rebalancer.topology.Topology;
+import org.testng.Assert;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import static org.mockito.Mockito.*;
+
+
+public class TestCardDealingAdjustmentAlgorithmV2 {
+  private Topology _topology;
+  private int[][] _defaultFaultZones = new int[][]{{1, 2, 3}, // zone0: i1, 
i2, i3
+  {4, 5, 6}, // zone1: i4, i5, i6
+  {7, 8, 9}  // zone0: i7, i8, i9
+  };
+
+  @BeforeClass
+  public void setUpTopology() {
+_topology = mock(Topology.class);
+
when(_topology.getFaultZones()).thenReturn(createFaultZones(_defaultFaultZones));
+  }
+
+  @Test(description = "Verify a few properties after algorithm instance is 
created")
+  public void testAlgorithmConstructor() {
+CardDealingAdjustmentAlgorithmV2 algorithm =
+new CardDealingAdjustmentAlgorithmV2(_topology, 3, 
CardDealingAdjustmentAlgorithmV2.Mode.EVENNESS);
+Map instanceWeights = algorithm.getInstanceWeight();
+// verify weight is set correctly
+for (Map.Entry entry : instanceWeights.entrySet()) {
+  if (entry.getKey().getId() != entry.getValue()) {
+Assert.fail(String.format("%s %s should have weight of %s", 
entry.getKey().getName(), entry.getKey().getId(),
+entry.getValue()));
+  }
+}
+Map faultZoneWeights = algorithm.getFaultZoneWeight();
+Map> faultZonePartationMap = 
algorithm.getFaultZonePartitionMap();
+Set faultZones = faultZoneWeights.keySet();
+
+Assert.assertEquals(faultZoneWeights.size(), 3);
+Assert.assertEquals(faultZonePartationMap.keySet(), faultZones);
+
+long sum = 0;
+for (long weight : faultZoneWeights.values()) {
+  sum += weight;
+}
+// verify total weight is computed correct
+if (sum != algorithm.getTotalWeight()) {
+  Assert.fail(String.format("total weight %s != total weight of zones %s", 
algorithm.getTotalWeight(), sum));
+}
+Map instanceFaultZone = algorithm.getInstanceFaultZone();
+Assert.assertEquals(instanceFaultZone.size(), 9);
+
+// verify zone mapping is correct
+for (Node zone : faultZones) {
+  long zoneId = zone.getId();
+  Set instanceIds = ImmutableSet.of(3 * zoneId + 1L, 3 * zoneId + 
2L, 3 * zoneId + 3L);
+  List instanceNodes = zone.getChildren();
+  Assert.assertEquals(instanceNodes.size(), 3);
+  Set actualInstanceIds = new HashSet<>();
+  for (Node node : instanceNodes) {
+actualInstanceIds.add(node.getId());
+  }
+  Assert.assertEquals(actualInstanceIds, instanceIds);
+}
+  }
+
+  @DataProvider
+  public static Object[][] stableComputingVerification() {
+return new Object[][]{
+// replica, repeatTimes, seed, true: evenness false: less movement
+{1, 10, 0, true}, {2, 10, 10, true}, {3, 10, 100, true}, {1, 10, 0, 
true}, {2, 10, 10, true},
+{3, 10, 100, true}, {1, 10, 0, true}, {2, 10, 10, true}, {3, 10, 100, 
true}, {1, 10, 0, false},
+{2, 10, 10, false}, {3, 10, 100, false}, {1, 10, 0, false}, {2, 10, 
10, false}, {3, 10, 100, false},
+{1, 10, 0, false}, {2, 10, 10, false}, {3, 10, 100, false}};
+  }
+
+  @Test(description = "Compute mapping multiple times, the mapping of 

[GitHub] [helix] narendly commented on a change in pull request #369: Add the workaround fix for assigning partitions when instance weight …

2019-08-02 Thread GitBox
narendly commented on a change in pull request #369: Add the workaround fix for 
assigning partitions when instance weight …
URL: https://github.com/apache/helix/pull/369#discussion_r310239874
 
 

 ##
 File path: 
helix-core/src/test/java/org/apache/helix/controller/rebalancer/strategy/crushMapping/TestCardDealingAdjustmentAlgorithmV2.java
 ##
 @@ -0,0 +1,328 @@
+package org.apache.helix.controller.rebalancer.strategy.crushMapping;
+
+/*
+ * 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 com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Sets;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import org.apache.helix.controller.rebalancer.topology.InstanceNode;
+import org.apache.helix.controller.rebalancer.topology.Node;
+import org.apache.helix.controller.rebalancer.topology.Topology;
+import org.testng.Assert;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import static org.mockito.Mockito.*;
+
+
+public class TestCardDealingAdjustmentAlgorithmV2 {
+  private Topology _topology;
+  private int[][] _defaultFaultZones = new int[][]{{1, 2, 3}, // zone0: i1, 
i2, i3
+  {4, 5, 6}, // zone1: i4, i5, i6
+  {7, 8, 9}  // zone0: i7, i8, i9
+  };
+
+  @BeforeClass
+  public void setUpTopology() {
+_topology = mock(Topology.class);
+
when(_topology.getFaultZones()).thenReturn(createFaultZones(_defaultFaultZones));
+  }
+
+  @Test(description = "Verify a few properties after algorithm instance is 
created")
+  public void testAlgorithmConstructor() {
+CardDealingAdjustmentAlgorithmV2 algorithm =
+new CardDealingAdjustmentAlgorithmV2(_topology, 3, 
CardDealingAdjustmentAlgorithmV2.Mode.EVENNESS);
+Map instanceWeights = algorithm.getInstanceWeight();
+// verify weight is set correctly
+for (Map.Entry entry : instanceWeights.entrySet()) {
+  if (entry.getKey().getId() != entry.getValue()) {
+Assert.fail(String.format("%s %s should have weight of %s", 
entry.getKey().getName(), entry.getKey().getId(),
+entry.getValue()));
+  }
+}
+Map faultZoneWeights = algorithm.getFaultZoneWeight();
+Map> faultZonePartationMap = 
algorithm.getFaultZonePartitionMap();
+Set faultZones = faultZoneWeights.keySet();
+
+Assert.assertEquals(faultZoneWeights.size(), 3);
+Assert.assertEquals(faultZonePartationMap.keySet(), faultZones);
+
+long sum = 0;
+for (long weight : faultZoneWeights.values()) {
+  sum += weight;
+}
+// verify total weight is computed correct
+if (sum != algorithm.getTotalWeight()) {
+  Assert.fail(String.format("total weight %s != total weight of zones %s", 
algorithm.getTotalWeight(), sum));
+}
+Map instanceFaultZone = algorithm.getInstanceFaultZone();
+Assert.assertEquals(instanceFaultZone.size(), 9);
+
+// verify zone mapping is correct
+for (Node zone : faultZones) {
+  long zoneId = zone.getId();
+  Set instanceIds = ImmutableSet.of(3 * zoneId + 1L, 3 * zoneId + 
2L, 3 * zoneId + 3L);
+  List instanceNodes = zone.getChildren();
+  Assert.assertEquals(instanceNodes.size(), 3);
+  Set actualInstanceIds = new HashSet<>();
+  for (Node node : instanceNodes) {
+actualInstanceIds.add(node.getId());
+  }
+  Assert.assertEquals(actualInstanceIds, instanceIds);
+}
+  }
+
+  @DataProvider
+  public static Object[][] stableComputingVerification() {
+return new Object[][]{
+// replica, repeatTimes, seed, true: evenness false: less movement
+{1, 10, 0, true}, {2, 10, 10, true}, {3, 10, 100, true}, {1, 10, 0, 
true}, {2, 10, 10, true},
+{3, 10, 100, true}, {1, 10, 0, true}, {2, 10, 10, true}, {3, 10, 100, 
true}, {1, 10, 0, false},
+{2, 10, 10, false}, {3, 10, 100, false}, {1, 10, 0, false}, {2, 10, 
10, false}, {3, 10, 100, false},
+{1, 10, 0, false}, {2, 10, 10, false}, {3, 10, 100, false}};
+  }
+
+  @Test(description = "Compute mapping multiple times, the mapping of 

[GitHub] [helix] narendly commented on a change in pull request #369: Add the workaround fix for assigning partitions when instance weight …

2019-08-02 Thread GitBox
narendly commented on a change in pull request #369: Add the workaround fix for 
assigning partitions when instance weight …
URL: https://github.com/apache/helix/pull/369#discussion_r310239254
 
 

 ##
 File path: 
helix-core/src/test/java/org/apache/helix/controller/rebalancer/strategy/crushMapping/TestCardDealingAdjustmentAlgorithmV2.java
 ##
 @@ -0,0 +1,328 @@
+package org.apache.helix.controller.rebalancer.strategy.crushMapping;
+
+/*
+ * 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 com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Sets;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import org.apache.helix.controller.rebalancer.topology.InstanceNode;
+import org.apache.helix.controller.rebalancer.topology.Node;
+import org.apache.helix.controller.rebalancer.topology.Topology;
+import org.testng.Assert;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import static org.mockito.Mockito.*;
+
+
+public class TestCardDealingAdjustmentAlgorithmV2 {
+  private Topology _topology;
+  private int[][] _defaultFaultZones = new int[][]{{1, 2, 3}, // zone0: i1, 
i2, i3
+  {4, 5, 6}, // zone1: i4, i5, i6
+  {7, 8, 9}  // zone0: i7, i8, i9
+  };
+
+  @BeforeClass
+  public void setUpTopology() {
+_topology = mock(Topology.class);
+
when(_topology.getFaultZones()).thenReturn(createFaultZones(_defaultFaultZones));
+  }
+
+  @Test(description = "Verify a few properties after algorithm instance is 
created")
+  public void testAlgorithmConstructor() {
+CardDealingAdjustmentAlgorithmV2 algorithm =
+new CardDealingAdjustmentAlgorithmV2(_topology, 3, 
CardDealingAdjustmentAlgorithmV2.Mode.EVENNESS);
+Map instanceWeights = algorithm.getInstanceWeight();
+// verify weight is set correctly
+for (Map.Entry entry : instanceWeights.entrySet()) {
+  if (entry.getKey().getId() != entry.getValue()) {
+Assert.fail(String.format("%s %s should have weight of %s", 
entry.getKey().getName(), entry.getKey().getId(),
+entry.getValue()));
+  }
+}
+Map faultZoneWeights = algorithm.getFaultZoneWeight();
+Map> faultZonePartationMap = 
algorithm.getFaultZonePartitionMap();
+Set faultZones = faultZoneWeights.keySet();
+
+Assert.assertEquals(faultZoneWeights.size(), 3);
+Assert.assertEquals(faultZonePartationMap.keySet(), faultZones);
+
+long sum = 0;
+for (long weight : faultZoneWeights.values()) {
+  sum += weight;
+}
+// verify total weight is computed correct
+if (sum != algorithm.getTotalWeight()) {
+  Assert.fail(String.format("total weight %s != total weight of zones %s", 
algorithm.getTotalWeight(), sum));
+}
+Map instanceFaultZone = algorithm.getInstanceFaultZone();
+Assert.assertEquals(instanceFaultZone.size(), 9);
 
 Review comment:
   Magic number 9! Let's make this a constant: `NUM_INSTANCES`.


This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
us...@infra.apache.org


With regards,
Apache Git Services


[GitHub] [helix] narendly commented on a change in pull request #369: Add the workaround fix for assigning partitions when instance weight …

2019-08-02 Thread GitBox
narendly commented on a change in pull request #369: Add the workaround fix for 
assigning partitions when instance weight …
URL: https://github.com/apache/helix/pull/369#discussion_r310239855
 
 

 ##
 File path: 
helix-core/src/test/java/org/apache/helix/controller/rebalancer/strategy/crushMapping/TestCardDealingAdjustmentAlgorithmV2.java
 ##
 @@ -0,0 +1,328 @@
+package org.apache.helix.controller.rebalancer.strategy.crushMapping;
+
+/*
+ * 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 com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Sets;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import org.apache.helix.controller.rebalancer.topology.InstanceNode;
+import org.apache.helix.controller.rebalancer.topology.Node;
+import org.apache.helix.controller.rebalancer.topology.Topology;
+import org.testng.Assert;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import static org.mockito.Mockito.*;
+
+
+public class TestCardDealingAdjustmentAlgorithmV2 {
+  private Topology _topology;
+  private int[][] _defaultFaultZones = new int[][]{{1, 2, 3}, // zone0: i1, 
i2, i3
+  {4, 5, 6}, // zone1: i4, i5, i6
+  {7, 8, 9}  // zone0: i7, i8, i9
+  };
+
+  @BeforeClass
+  public void setUpTopology() {
+_topology = mock(Topology.class);
+
when(_topology.getFaultZones()).thenReturn(createFaultZones(_defaultFaultZones));
+  }
+
+  @Test(description = "Verify a few properties after algorithm instance is 
created")
+  public void testAlgorithmConstructor() {
+CardDealingAdjustmentAlgorithmV2 algorithm =
+new CardDealingAdjustmentAlgorithmV2(_topology, 3, 
CardDealingAdjustmentAlgorithmV2.Mode.EVENNESS);
+Map instanceWeights = algorithm.getInstanceWeight();
+// verify weight is set correctly
+for (Map.Entry entry : instanceWeights.entrySet()) {
+  if (entry.getKey().getId() != entry.getValue()) {
+Assert.fail(String.format("%s %s should have weight of %s", 
entry.getKey().getName(), entry.getKey().getId(),
+entry.getValue()));
+  }
+}
+Map faultZoneWeights = algorithm.getFaultZoneWeight();
+Map> faultZonePartationMap = 
algorithm.getFaultZonePartitionMap();
+Set faultZones = faultZoneWeights.keySet();
+
+Assert.assertEquals(faultZoneWeights.size(), 3);
+Assert.assertEquals(faultZonePartationMap.keySet(), faultZones);
+
+long sum = 0;
+for (long weight : faultZoneWeights.values()) {
+  sum += weight;
+}
+// verify total weight is computed correct
+if (sum != algorithm.getTotalWeight()) {
+  Assert.fail(String.format("total weight %s != total weight of zones %s", 
algorithm.getTotalWeight(), sum));
+}
+Map instanceFaultZone = algorithm.getInstanceFaultZone();
+Assert.assertEquals(instanceFaultZone.size(), 9);
+
+// verify zone mapping is correct
+for (Node zone : faultZones) {
+  long zoneId = zone.getId();
+  Set instanceIds = ImmutableSet.of(3 * zoneId + 1L, 3 * zoneId + 
2L, 3 * zoneId + 3L);
+  List instanceNodes = zone.getChildren();
+  Assert.assertEquals(instanceNodes.size(), 3);
+  Set actualInstanceIds = new HashSet<>();
+  for (Node node : instanceNodes) {
+actualInstanceIds.add(node.getId());
+  }
+  Assert.assertEquals(actualInstanceIds, instanceIds);
+}
+  }
+
+  @DataProvider
+  public static Object[][] stableComputingVerification() {
+return new Object[][]{
+// replica, repeatTimes, seed, true: evenness false: less movement
+{1, 10, 0, true}, {2, 10, 10, true}, {3, 10, 100, true}, {1, 10, 0, 
true}, {2, 10, 10, true},
+{3, 10, 100, true}, {1, 10, 0, true}, {2, 10, 10, true}, {3, 10, 100, 
true}, {1, 10, 0, false},
+{2, 10, 10, false}, {3, 10, 100, false}, {1, 10, 0, false}, {2, 10, 
10, false}, {3, 10, 100, false},
+{1, 10, 0, false}, {2, 10, 10, false}, {3, 10, 100, false}};
+  }
+
+  @Test(description = "Compute mapping multiple times, the mapping of 

[GitHub] [helix] narendly commented on a change in pull request #369: Add the workaround fix for assigning partitions when instance weight …

2019-08-02 Thread GitBox
narendly commented on a change in pull request #369: Add the workaround fix for 
assigning partitions when instance weight …
URL: https://github.com/apache/helix/pull/369#discussion_r310236475
 
 

 ##
 File path: 
helix-core/src/test/java/org/apache/helix/controller/rebalancer/strategy/crushMapping/TestCardDealingAdjustmentAlgorithmV2.java
 ##
 @@ -0,0 +1,328 @@
+package org.apache.helix.controller.rebalancer.strategy.crushMapping;
+
+/*
+ * 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 com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Sets;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import org.apache.helix.controller.rebalancer.topology.InstanceNode;
+import org.apache.helix.controller.rebalancer.topology.Node;
+import org.apache.helix.controller.rebalancer.topology.Topology;
+import org.testng.Assert;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import static org.mockito.Mockito.*;
+
+
+public class TestCardDealingAdjustmentAlgorithmV2 {
+  private Topology _topology;
+  private int[][] _defaultFaultZones = new int[][]{{1, 2, 3}, // zone0: i1, 
i2, i3
+  {4, 5, 6}, // zone1: i4, i5, i6
+  {7, 8, 9}  // zone0: i7, i8, i9
+  };
+
+  @BeforeClass
+  public void setUpTopology() {
+_topology = mock(Topology.class);
+
when(_topology.getFaultZones()).thenReturn(createFaultZones(_defaultFaultZones));
+  }
+
+  @Test(description = "Verify a few properties after algorithm instance is 
created")
+  public void testAlgorithmConstructor() {
+CardDealingAdjustmentAlgorithmV2 algorithm =
+new CardDealingAdjustmentAlgorithmV2(_topology, 3, 
CardDealingAdjustmentAlgorithmV2.Mode.EVENNESS);
+Map instanceWeights = algorithm.getInstanceWeight();
+// verify weight is set correctly
+for (Map.Entry entry : instanceWeights.entrySet()) {
+  if (entry.getKey().getId() != entry.getValue()) {
+Assert.fail(String.format("%s %s should have weight of %s", 
entry.getKey().getName(), entry.getKey().getId(),
+entry.getValue()));
+  }
+}
+Map faultZoneWeights = algorithm.getFaultZoneWeight();
+Map> faultZonePartationMap = 
algorithm.getFaultZonePartitionMap();
+Set faultZones = faultZoneWeights.keySet();
+
+Assert.assertEquals(faultZoneWeights.size(), 3);
+Assert.assertEquals(faultZonePartationMap.keySet(), faultZones);
+
+long sum = 0;
+for (long weight : faultZoneWeights.values()) {
+  sum += weight;
+}
+// verify total weight is computed correct
+if (sum != algorithm.getTotalWeight()) {
+  Assert.fail(String.format("total weight %s != total weight of zones %s", 
algorithm.getTotalWeight(), sum));
+}
+Map instanceFaultZone = algorithm.getInstanceFaultZone();
+Assert.assertEquals(instanceFaultZone.size(), 9);
+
+// verify zone mapping is correct
+for (Node zone : faultZones) {
+  long zoneId = zone.getId();
+  Set instanceIds = ImmutableSet.of(3 * zoneId + 1L, 3 * zoneId + 
2L, 3 * zoneId + 3L);
+  List instanceNodes = zone.getChildren();
+  Assert.assertEquals(instanceNodes.size(), 3);
+  Set actualInstanceIds = new HashSet<>();
+  for (Node node : instanceNodes) {
+actualInstanceIds.add(node.getId());
+  }
+  Assert.assertEquals(actualInstanceIds, instanceIds);
+}
+  }
+
+  @DataProvider
+  public static Object[][] stableComputingVerification() {
+return new Object[][]{
+// replica, repeatTimes, seed, true: evenness false: less movement
+{1, 10, 0, true}, {2, 10, 10, true}, {3, 10, 100, true}, {1, 10, 0, 
true}, {2, 10, 10, true},
+{3, 10, 100, true}, {1, 10, 0, true}, {2, 10, 10, true}, {3, 10, 100, 
true}, {1, 10, 0, false},
+{2, 10, 10, false}, {3, 10, 100, false}, {1, 10, 0, false}, {2, 10, 
10, false}, {3, 10, 100, false},
+{1, 10, 0, false}, {2, 10, 10, false}, {3, 10, 100, false}};
+  }
+
+  @Test(description = "Compute mapping multiple times, the mapping of 

[GitHub] [helix] narendly commented on a change in pull request #369: Add the workaround fix for assigning partitions when instance weight …

2019-08-02 Thread GitBox
narendly commented on a change in pull request #369: Add the workaround fix for 
assigning partitions when instance weight …
URL: https://github.com/apache/helix/pull/369#discussion_r310234688
 
 

 ##
 File path: 
helix-core/src/main/java/org/apache/helix/controller/rebalancer/topology/Node.java
 ##
 @@ -36,6 +36,11 @@
 
   public Node() { }
 
+  public Node(String name, long id) {
 
 Review comment:
   I think this is a minor point. Alternatively, you could just use the empty 
constructor and call set methods but either way I think would work? 


This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
us...@infra.apache.org


With regards,
Apache Git Services


[GitHub] [helix] narendly commented on a change in pull request #369: Add the workaround fix for assigning partitions when instance weight …

2019-08-02 Thread GitBox
narendly commented on a change in pull request #369: Add the workaround fix for 
assigning partitions when instance weight …
URL: https://github.com/apache/helix/pull/369#discussion_r310234688
 
 

 ##
 File path: 
helix-core/src/main/java/org/apache/helix/controller/rebalancer/topology/Node.java
 ##
 @@ -36,6 +36,11 @@
 
   public Node() { }
 
+  public Node(String name, long id) {
 
 Review comment:
   I think this is a minor point. Alternatively, you could just use the empty 
constructor and call set methods but either way I think would work?


This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
us...@infra.apache.org


With regards,
Apache Git Services


[GitHub] [helix] narendly commented on a change in pull request #369: Add the workaround fix for assigning partitions when instance weight …

2019-08-02 Thread GitBox
narendly commented on a change in pull request #369: Add the workaround fix for 
assigning partitions when instance weight …
URL: https://github.com/apache/helix/pull/369#discussion_r310233448
 
 

 ##
 File path: 
helix-core/src/test/java/org/apache/helix/controller/rebalancer/strategy/crushMapping/TestCardDealingAdjustmentAlgorithmV2.java
 ##
 @@ -0,0 +1,328 @@
+package org.apache.helix.controller.rebalancer.strategy.crushMapping;
+
+/*
+ * 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 com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Sets;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import org.apache.helix.controller.rebalancer.topology.InstanceNode;
+import org.apache.helix.controller.rebalancer.topology.Node;
+import org.apache.helix.controller.rebalancer.topology.Topology;
+import org.testng.Assert;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import static org.mockito.Mockito.*;
+
+
+public class TestCardDealingAdjustmentAlgorithmV2 {
+  private Topology _topology;
+  private int[][] _defaultFaultZones = new int[][]{{1, 2, 3}, // zone0: i1, 
i2, i3
+  {4, 5, 6}, // zone1: i4, i5, i6
+  {7, 8, 9}  // zone0: i7, i8, i9
+  };
+
+  @BeforeClass
+  public void setUpTopology() {
+_topology = mock(Topology.class);
+
when(_topology.getFaultZones()).thenReturn(createFaultZones(_defaultFaultZones));
+  }
+
+  @Test(description = "Verify a few properties after algorithm instance is 
created")
 
 Review comment:
   I like how you consistently add the description. Here, though, could you add 
a few lines on what properties are tested?


This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
us...@infra.apache.org


With regards,
Apache Git Services


[GitHub] [helix] narendly commented on a change in pull request #369: Add the workaround fix for assigning partitions when instance weight …

2019-08-02 Thread GitBox
narendly commented on a change in pull request #369: Add the workaround fix for 
assigning partitions when instance weight …
URL: https://github.com/apache/helix/pull/369#discussion_r310233448
 
 

 ##
 File path: 
helix-core/src/test/java/org/apache/helix/controller/rebalancer/strategy/crushMapping/TestCardDealingAdjustmentAlgorithmV2.java
 ##
 @@ -0,0 +1,328 @@
+package org.apache.helix.controller.rebalancer.strategy.crushMapping;
+
+/*
+ * 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 com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Sets;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import org.apache.helix.controller.rebalancer.topology.InstanceNode;
+import org.apache.helix.controller.rebalancer.topology.Node;
+import org.apache.helix.controller.rebalancer.topology.Topology;
+import org.testng.Assert;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import static org.mockito.Mockito.*;
+
+
+public class TestCardDealingAdjustmentAlgorithmV2 {
+  private Topology _topology;
+  private int[][] _defaultFaultZones = new int[][]{{1, 2, 3}, // zone0: i1, 
i2, i3
+  {4, 5, 6}, // zone1: i4, i5, i6
+  {7, 8, 9}  // zone0: i7, i8, i9
+  };
+
+  @BeforeClass
+  public void setUpTopology() {
+_topology = mock(Topology.class);
+
when(_topology.getFaultZones()).thenReturn(createFaultZones(_defaultFaultZones));
+  }
+
+  @Test(description = "Verify a few properties after algorithm instance is 
created")
 
 Review comment:
   I like how you consistently add the description. Here, though, could you add 
a few lines on what properties are tested?


This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
us...@infra.apache.org


With regards,
Apache Git Services


[GitHub] [helix] narendly commented on a change in pull request #333: Fix issue when client only sets ANY at cluster level throttle config

2019-08-02 Thread GitBox
narendly commented on a change in pull request #333: Fix issue when client only 
sets ANY at cluster level throttle config
URL: https://github.com/apache/helix/pull/333#discussion_r310232277
 
 

 ##
 File path: 
helix-core/src/main/java/org/apache/helix/controller/stages/StateTransitionThrottleController.java
 ##
 @@ -99,6 +99,21 @@ public StateTransitionThrottleController(Set 
resources, ClusterConfig cl
 }
   }
 
+  // The getter methods are used for debugging and testing purpose
 
 Review comment:
   Yes, you would need to make the relevant fields `protected` (that was 
implied). `protected` should be good enough as long as we don't make it 
`public`. The point here is to avoid adding methods that aren't strictly part 
of the class logic :)


This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
us...@infra.apache.org


With regards,
Apache Git Services


[GitHub] [helix] narendly commented on a change in pull request #333: Fix issue when client only sets ANY at cluster level throttle config

2019-08-02 Thread GitBox
narendly commented on a change in pull request #333: Fix issue when client only 
sets ANY at cluster level throttle config
URL: https://github.com/apache/helix/pull/333#discussion_r310232277
 
 

 ##
 File path: 
helix-core/src/main/java/org/apache/helix/controller/stages/StateTransitionThrottleController.java
 ##
 @@ -99,6 +99,21 @@ public StateTransitionThrottleController(Set 
resources, ClusterConfig cl
 }
   }
 
+  // The getter methods are used for debugging and testing purpose
 
 Review comment:
   Yes, you would need to make the relevant fields `protected`. That was 
implied. `protected` should be good enough as long as we don't make it 
`public`. The point here is to avoid adding methods that aren't strictly part 
of the class logic :)


This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
us...@infra.apache.org


With regards,
Apache Git Services


[GitHub] [helix] narendly commented on a change in pull request #333: Fix issue when client only sets ANY at cluster level throttle config

2019-08-02 Thread GitBox
narendly commented on a change in pull request #333: Fix issue when client only 
sets ANY at cluster level throttle config
URL: https://github.com/apache/helix/pull/333#discussion_r310230832
 
 

 ##
 File path: 
helix-core/src/main/java/org/apache/helix/controller/stages/StateTransitionThrottleController.java
 ##
 @@ -208,13 +210,20 @@ protected void 
chargeResource(StateTransitionThrottleConfig.RebalanceType rebala
*/
   protected void chargeInstance(StateTransitionThrottleConfig.RebalanceType 
rebalanceType,
   String instance) {
-if (_pendingTransitionAllowedPerInstance.containsKey(instance)
-&& 
_pendingTransitionAllowedPerInstance.get(instance).containsKey(rebalanceType)) {
-  chargeANYType(_pendingTransitionAllowedPerInstance.get(instance));
-  Long instanceThrottle = 
_pendingTransitionAllowedPerInstance.get(instance).get(rebalanceType);
-  if (instanceThrottle > 0) {
-_pendingTransitionAllowedPerInstance.get(instance).put(rebalanceType, 
instanceThrottle - 1);
-  }
+charge(rebalanceType, 
_pendingTransitionAllowedPerInstance.getOrDefault(instance, new HashMap<>()));
+  }
+
+  private void charge(StateTransitionThrottleConfig.RebalanceType 
rebalanceType,
+  Map quota) {
+if 
(StateTransitionThrottleConfig.RebalanceType.NONE.equals(rebalanceType)) {
+  logger.error("Wrong rebalance type NONE as parameter");
+  return;
+}
+// if ANY type is present, decrement one else do nothing
+quota.computeIfPresent(StateTransitionThrottleConfig.RebalanceType.ANY, 
(key, val) -> Math.max(0, val - 1));
 
 Review comment:
   I see what you were saying earlier. You could do `(type, quotaCount)` or 
something similar. Point is to make the code a little more readable :)


This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
us...@infra.apache.org


With regards,
Apache Git Services


[GitHub] [helix] i3wangyi commented on a change in pull request #333: Fix issue when client only sets ANY at cluster level throttle config

2019-08-02 Thread GitBox
i3wangyi commented on a change in pull request #333: Fix issue when client only 
sets ANY at cluster level throttle config
URL: https://github.com/apache/helix/pull/333#discussion_r310226396
 
 

 ##
 File path: 
helix-core/src/main/java/org/apache/helix/controller/stages/StateTransitionThrottleController.java
 ##
 @@ -208,13 +210,20 @@ protected void 
chargeResource(StateTransitionThrottleConfig.RebalanceType rebala
*/
   protected void chargeInstance(StateTransitionThrottleConfig.RebalanceType 
rebalanceType,
   String instance) {
-if (_pendingTransitionAllowedPerInstance.containsKey(instance)
-&& 
_pendingTransitionAllowedPerInstance.get(instance).containsKey(rebalanceType)) {
-  chargeANYType(_pendingTransitionAllowedPerInstance.get(instance));
-  Long instanceThrottle = 
_pendingTransitionAllowedPerInstance.get(instance).get(rebalanceType);
-  if (instanceThrottle > 0) {
-_pendingTransitionAllowedPerInstance.get(instance).put(rebalanceType, 
instanceThrottle - 1);
-  }
+charge(rebalanceType, 
_pendingTransitionAllowedPerInstance.getOrDefault(instance, new HashMap<>()));
+  }
+
+  private void charge(StateTransitionThrottleConfig.RebalanceType 
rebalanceType,
+  Map quota) {
+if 
(StateTransitionThrottleConfig.RebalanceType.NONE.equals(rebalanceType)) {
+  logger.error("Wrong rebalance type NONE as parameter");
+  return;
+}
+// if ANY type is present, decrement one else do nothing
+quota.computeIfPresent(StateTransitionThrottleConfig.RebalanceType.ANY, 
(key, val) -> Math.max(0, val - 1));
 
 Review comment:
   Look at the method parameter, these names are already taken


This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
us...@infra.apache.org


With regards,
Apache Git Services


[GitHub] [helix] narendly commented on a change in pull request #362: The WAGED rebalancer cluster model implementation

2019-08-02 Thread GitBox
narendly commented on a change in pull request #362: The WAGED rebalancer 
cluster model implementation
URL: https://github.com/apache/helix/pull/362#discussion_r309939372
 
 

 ##
 File path: 
helix-core/src/main/java/org/apache/helix/controller/rebalancer/waged/model/ClusterModel.java
 ##
 @@ -19,9 +19,131 @@
  * under the License.
  */
 
+import org.apache.helix.HelixException;
+import org.apache.helix.model.IdealState;
+
+import java.util.Collections;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
+
 /**
- * A placeholder before we have the implementation.
- *
  * This class wraps the required input for the rebalance algorithm.
  */
-public class ClusterModel { }
+public class ClusterModel {
+  private final ClusterContext _clusterContext;
+  // Map to track all the assignable replications. >
+  private final Map> _assignableReplicas;
+  // The index to find the replication information with a certain state. 
>
+  // Note that the identical replicas are dedupe in the index.
 
 Review comment:
   deduped


This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
us...@infra.apache.org


With regards,
Apache Git Services


[GitHub] [helix] narendly commented on a change in pull request #362: The WAGED rebalancer cluster model implementation

2019-08-02 Thread GitBox
narendly commented on a change in pull request #362: The WAGED rebalancer 
cluster model implementation
URL: https://github.com/apache/helix/pull/362#discussion_r310213495
 
 

 ##
 File path: 
helix-core/src/test/java/org/apache/helix/controller/rebalancer/waged/model/TestAssignableNode.java
 ##
 @@ -0,0 +1,203 @@
+package org.apache.helix.controller.rebalancer.waged.model;
+
+/*
+ * 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 org.apache.helix.HelixException;
+import 
org.apache.helix.controller.dataproviders.ResourceControllerDataProvider;
+import org.apache.helix.integration.task.TaskTestBase;
+import org.apache.helix.model.BuiltInStateModelDefinitions;
+import org.apache.helix.model.ClusterConfig;
+import org.apache.helix.model.CurrentState;
+import org.apache.helix.model.InstanceConfig;
+import org.apache.helix.model.LiveInstance;
+import org.apache.helix.model.ResourceConfig;
+import org.mockito.Mockito;
+import org.testng.Assert;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import static org.mockito.Mockito.when;
+
+public class TestAssignableNode extends AbstractTestClusterModel {
+  @BeforeClass
+  public void initialize() {
+super.initialize();
+  }
+
+  @Test
+  public void testNormalUsage() throws IOException {
+ResourceControllerDataProvider testCache = setupClusterDataCache();
+Set assignmentSet = generateReplicas(testCache);
+
+// Test 1 - initialization
+
+Set expectedAssignmentSet1 = new 
HashSet<>(_partitionNames.subList(0, 2));
+Set expectedAssignmentSet2 = new 
HashSet<>(_partitionNames.subList(2, 4));
+Map> expectedAssignment = new HashMap<>();
+expectedAssignment.put("Resource1", expectedAssignmentSet1);
+expectedAssignment.put("Resource2", expectedAssignmentSet2);
+Map expectedCapacityMap = new HashMap<>();
+expectedCapacityMap.put("item1", 4);
+expectedCapacityMap.put("item2", 8);
+expectedCapacityMap.put("item3", 30);
+
+
+AssignableNode assignableNode = new AssignableNode(testCache, 
_testInstanceId, assignmentSet);
+
Assert.assertTrue(assignableNode.getCurrentAssignmentsMap().equals(expectedAssignment));
+Assert.assertEquals(assignableNode.getCurrentAssignmentCount(), 4);
+Assert.assertEquals(assignableNode.getHighestCapacityUtilization(), 16.0 / 
20.0, 0.005);
+
Assert.assertTrue(assignableNode.getMaxCapacity().equals(_capacityDataMap));
+Assert.assertEquals(assignableNode.getMaxPartition(), 5);
+Assert.assertEquals(assignableNode.getInstanceTags(), _testInstanceTags);
+Assert.assertEquals(assignableNode.getFaultZone(), _testFaultZoneId);
+
Assert.assertTrue(assignableNode.getDisabledPartitionsMap().equals(_disabledPartitionsMap));
+
Assert.assertTrue(assignableNode.getCurrentCapacity().equals(expectedCapacityMap));
+
+// Test 2 - reduce assignment
 
 Review comment:
   Explain please? What does it mean to reduce assignment?


This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
us...@infra.apache.org


With regards,
Apache Git Services


[GitHub] [helix] narendly commented on a change in pull request #362: The WAGED rebalancer cluster model implementation

2019-08-02 Thread GitBox
narendly commented on a change in pull request #362: The WAGED rebalancer 
cluster model implementation
URL: https://github.com/apache/helix/pull/362#discussion_r310218704
 
 

 ##
 File path: 
helix-core/src/test/java/org/apache/helix/controller/rebalancer/waged/model/TestClusterContext.java
 ##
 @@ -0,0 +1,93 @@
+package org.apache.helix.controller.rebalancer.waged.model;
+
+/*
+ * 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 org.apache.helix.HelixException;
+import 
org.apache.helix.controller.dataproviders.ResourceControllerDataProvider;
+import org.testng.Assert;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+import java.io.IOException;
+import java.util.Collections;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import static java.util.stream.Collectors.toSet;
+
+public class TestClusterContext extends AbstractTestClusterModel {
+  @BeforeClass
+  public void initialize() {
+super.initialize();
+  }
+
+  @Test
+  public void testNormalUsage() throws IOException {
+ResourceControllerDataProvider testCache = setupClusterDataCache();
+Set assignmentSet = generateReplicas(testCache);
+
+// Test 1 - initialization
+ClusterContext context = new ClusterContext(assignmentSet, 2);
+
+// Note that we leaved some margin for the max estimation.
+Assert.assertEquals(context.getEstimatedMaxPartitionCount(), 3);
+Assert.assertEquals(context.getEstimatedMaxTopStateCount(), 2);
+Assert.assertEquals(context.getAssignmentForFaultZoneMap(), 
Collections.emptyMap());
+for (String resourceName : _resourceNames) {
+  
Assert.assertEquals(context.getEstimatedMaxPartitionByResource(resourceName), 
2);
+  Assert.assertEquals(
+  context.getPartitionsForResourceAndFaultZone(_testFaultZoneId, 
resourceName),
+  Collections.emptySet());
+}
+
+// Assign
+Map>> expectedFaultZoneMap = Collections
+.singletonMap(_testFaultZoneId, 
assignmentSet.stream().collect(Collectors
+.groupingBy(AssignableReplica::getResourceName,
+Collectors.mapping(AssignableReplica::getPartitionName, 
toSet();
+
+assignmentSet.stream().forEach(r -> context
+.addPartitionToFaultZone(_testFaultZoneId, r.getResourceName(), 
r.getPartitionName()));
+Assert.assertEquals(context.getAssignmentForFaultZoneMap(), 
expectedFaultZoneMap);
+
+// release
+
Assert.assertTrue(expectedFaultZoneMap.get(_testFaultZoneId).get(_resourceNames.get(0))
+.remove(_partitionNames.get(0)));
+context.removePartitionFromFaultZone(_testFaultZoneId, 
_resourceNames.get(0),
+_partitionNames.get(0));
+
+Assert.assertEquals(context.getAssignmentForFaultZoneMap(), 
expectedFaultZoneMap);
+  }
+
+  @Test(expectedExceptions = HelixException.class, 
expectedExceptionsMessageRegExp = "Resource Resource1 already has a replica 
from partition Partition1 in fault zone testZone")
+  public void testAssignAlreadyExist() throws IOException {
 
 Review comment:
   AssignExistingReplica?


This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
us...@infra.apache.org


With regards,
Apache Git Services


[GitHub] [helix] narendly commented on a change in pull request #362: The WAGED rebalancer cluster model implementation

2019-08-02 Thread GitBox
narendly commented on a change in pull request #362: The WAGED rebalancer 
cluster model implementation
URL: https://github.com/apache/helix/pull/362#discussion_r310212807
 
 

 ##
 File path: 
helix-core/src/test/java/org/apache/helix/controller/rebalancer/waged/model/AbstractTestClusterModel.java
 ##
 @@ -0,0 +1,161 @@
+package org.apache.helix.controller.rebalancer.waged.model;
+
+/*
+ * 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 
org.apache.helix.controller.dataproviders.ResourceControllerDataProvider;
+import org.apache.helix.model.BuiltInStateModelDefinitions;
+import org.apache.helix.model.ClusterConfig;
+import org.apache.helix.model.CurrentState;
+import org.apache.helix.model.InstanceConfig;
+import org.apache.helix.model.LiveInstance;
+import org.apache.helix.model.ResourceConfig;
+import org.mockito.Mockito;
+import org.testng.annotations.BeforeClass;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import static org.mockito.Mockito.when;
+
+public abstract class AbstractTestClusterModel {
+  protected String _testInstanceId;
+  protected List _resourceNames;
+  protected List _partitionNames;
+  protected Map _capacityDataMap;
+  protected Map> _disabledPartitionsMap;
+  protected List _testInstanceTags;
+  protected String _testFaultZoneId;
+
+  @BeforeClass
+  public void initialize() {
+_testInstanceId = "testInstanceId";
+_resourceNames = new ArrayList<>();
+_resourceNames.add("Resource1");
+_resourceNames.add("Resource2");
+_partitionNames = new ArrayList<>();
+_partitionNames.add("Partition1");
+_partitionNames.add("Partition2");
+_partitionNames.add("Partition3");
+_partitionNames.add("Partition4");
+_capacityDataMap = new HashMap<>();
+_capacityDataMap.put("item1", 20);
+_capacityDataMap.put("item2", 40);
+_capacityDataMap.put("item3", 30);
+List disabledPartitions = new ArrayList<>();
+disabledPartitions.add("TestPartition");
+_disabledPartitionsMap = new HashMap<>();
+_disabledPartitionsMap.put("TestResource", disabledPartitions);
+_testInstanceTags = new ArrayList<>();
+_testInstanceTags.add("TestTag");
+_testFaultZoneId = "testZone";
+  }
+
+  protected ResourceControllerDataProvider setupClusterDataCache() throws 
IOException {
+ResourceControllerDataProvider testCache = 
Mockito.mock(ResourceControllerDataProvider.class);
+
+InstanceConfig testInstanceConfig = new InstanceConfig("testInstanceId");
+testInstanceConfig.setInstanceCapacityMap(_capacityDataMap);
+testInstanceConfig.addTag(_testInstanceTags.get(0));
+testInstanceConfig.setInstanceEnabledForPartition("TestResource", 
"TestPartition", false);
+testInstanceConfig.setInstanceEnabled(true);
+testInstanceConfig.setZoneId(_testFaultZoneId);
+Map instanceConfigMap = new HashMap<>();
+instanceConfigMap.put(_testInstanceId, testInstanceConfig);
+when(testCache.getInstanceConfigMap()).thenReturn(instanceConfigMap);
+
+ClusterConfig testClusterConfig = new ClusterConfig("testClusterConfigId");
+testClusterConfig.setMaxPartitionsPerInstance(5);
+testClusterConfig.setDisabledInstances(Collections.emptyMap());
+testClusterConfig.setTopologyAwareEnabled(false);
+when(testCache.getClusterConfig()).thenReturn(testClusterConfig);
+
+LiveInstance testLiveInstance = new LiveInstance(_testInstanceId);
+testLiveInstance.setSessionId("testSessionId");
+Map liveInstanceMap = new HashMap<>();
+liveInstanceMap.put(_testInstanceId, testLiveInstance);
+when(testCache.getLiveInstances()).thenReturn(liveInstanceMap);
+
+CurrentState testCurrentStateResource1 = Mockito.mock(CurrentState.class);
+Map partitionStateMap1 = new HashMap<>();
+partitionStateMap1.put(_partitionNames.get(0), "MASTER");
+partitionStateMap1.put(_partitionNames.get(1), "SLAVE");
+
when(testCurrentStateResource1.getResourceName()).thenReturn(_resourceNames.get(0));
+

[GitHub] [helix] narendly commented on a change in pull request #362: The WAGED rebalancer cluster model implementation

2019-08-02 Thread GitBox
narendly commented on a change in pull request #362: The WAGED rebalancer 
cluster model implementation
URL: https://github.com/apache/helix/pull/362#discussion_r310170701
 
 

 ##
 File path: 
helix-core/src/main/java/org/apache/helix/controller/rebalancer/waged/model/ClusterModel.java
 ##
 @@ -19,9 +19,131 @@
  * under the License.
  */
 
+import org.apache.helix.HelixException;
+import org.apache.helix.model.IdealState;
+
+import java.util.Collections;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
+
 /**
- * A placeholder before we have the implementation.
- *
  * This class wraps the required input for the rebalance algorithm.
  */
-public class ClusterModel { }
+public class ClusterModel {
+  private final ClusterContext _clusterContext;
+  // Map to track all the assignable replications. >
+  private final Map> _assignableReplicas;
+  // The index to find the replication information with a certain state. 
>
+  // Note that the identical replicas are dedupe in the index.
+  private final Map> 
_assignableReplicaIndex;
+  private final Map _assignableNodeMap;
+
+  // Records about the previous assignment
+  private final Map _baselineAssignment;
+  private final Map _bestPossibleAssignment;
+
+  /**
+   * @param clusterContext The initialized cluster context.
+   * @param assignableReplicas The replications to be assigned.
+   *   Note that the replicas in this list shall 
not be included while initializing the context and assignable nodes.
+   * @param assignableNodesThe active instances.
+   * @param baselineAssignment The recorded baseline assignment.
+   * @param bestPossibleAssignment The current best possible assignment.
+   */
+  ClusterModel(ClusterContext clusterContext, Set 
assignableReplicas,
+  Set assignableNodes, Map 
baselineAssignment,
+  Map bestPossibleAssignment) {
+_clusterContext = clusterContext;
+
+// Save all the to be assigned replication
+_assignableReplicas = assignableReplicas.stream()
+.collect(Collectors.groupingBy(AssignableReplica::getResourceName, 
Collectors.toSet()));
+
+// Index all the replicas to be assigned. Dedup the replica if two 
instances have the same resource/partition/state
+_assignableReplicaIndex = assignableReplicas.stream().collect(Collectors
+.groupingBy(AssignableReplica::getResourceName, Collectors
+.toMap(AssignableReplica::toString, replica -> replica,
+(oldValue, newValue) -> oldValue)));
+
+_assignableNodeMap = assignableNodes.stream()
+.collect(Collectors.toMap(AssignableNode::getInstanceName, node -> 
node));
+
+_baselineAssignment = baselineAssignment;
+_bestPossibleAssignment = bestPossibleAssignment;
+  }
+
+  public ClusterContext getContext() {
+return _clusterContext;
+  }
+
+  public Map getAssignableNodes() {
+return _assignableNodeMap;
+  }
+
+  public Map> getAssignableReplicas() {
+return _assignableReplicas;
+  }
+
+  public Map getBaseline() {
+return _baselineAssignment;
+  }
+
+  public Map getBestPossibleAssignment() {
+return _bestPossibleAssignment;
+  }
+
+  /**
+   * Propose the assignment to the cluster model.
 
 Review comment:
   Rephrase? This description doesn't make sense. Say "Try to make an 
assignment for a given replica on the given instance. Note that this may not 
show up in the final assignment - this assignment may be released and 
re-assigned elsewhere."


This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
us...@infra.apache.org


With regards,
Apache Git Services


[GitHub] [helix] narendly commented on a change in pull request #362: The WAGED rebalancer cluster model implementation

2019-08-02 Thread GitBox
narendly commented on a change in pull request #362: The WAGED rebalancer 
cluster model implementation
URL: https://github.com/apache/helix/pull/362#discussion_r310223885
 
 

 ##
 File path: 
helix-core/src/test/java/org/apache/helix/controller/rebalancer/waged/model/TestClusterModel.java
 ##
 @@ -0,0 +1,108 @@
+package org.apache.helix.controller.rebalancer.waged.model;
+
+/*
+ * 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 org.apache.helix.HelixException;
+import 
org.apache.helix.controller.dataproviders.ResourceControllerDataProvider;
+import org.testng.Assert;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+import java.io.IOException;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
+public class TestClusterModel extends AbstractTestClusterModel {
+  @BeforeClass
+  public void initialize() {
+super.initialize();
+  }
+
+  Set generateNodes(ResourceControllerDataProvider testCache) {
+Set nodeSet = new HashSet<>();
+testCache.getInstanceConfigMap().values().stream().forEach(config -> 
nodeSet
+.add(new AssignableNode(testCache, config.getInstanceName(), 
Collections.emptyList(;
+return nodeSet;
+  }
+
+  @Test
+  public void testNormalUsage() throws IOException {
+ResourceControllerDataProvider testCache = setupClusterDataCache();
+Set assignableReplicas = generateReplicas(testCache);
+Set assignableNodes = generateNodes(testCache);
+
+// Test 1 - initialization
+ClusterContext context = new ClusterContext(assignableReplicas, 2);
+ClusterModel clusterModel =
+new ClusterModel(context, assignableReplicas, assignableNodes, 
Collections.emptyMap(),
+Collections.emptyMap());
+
+
Assert.assertTrue(clusterModel.getContext().getAssignmentForFaultZoneMap().values().stream()
+.allMatch(v -> v.values().isEmpty()));
+Assert.assertFalse(clusterModel.getAssignableNodes().values().stream()
+.anyMatch(n -> n.getCurrentAssignmentCount() != 0));
+
+// The initialization of the context, node and replication has been tested 
separately. So for
+// cluster model, focus on testing the assignment and release.
+
+// Assign
+AssignableReplica replica = assignableReplicas.iterator().next();
+AssignableNode node = assignableNodes.iterator().next();
+clusterModel
+.assign(replica.getResourceName(), replica.getPartitionName(), 
replica.getReplicaState(),
+node.getInstanceName());
+
+Assert.assertTrue(
+
clusterModel.getContext().getAssignmentForFaultZoneMap().get(node.getFaultZone())
+
.get(replica.getResourceName()).contains(replica.getPartitionName()));
+
Assert.assertTrue(node.getCurrentAssignmentsMap().get(replica.getResourceName())
+.contains(replica.getPartitionName()));
+
+// Assign a non-exist replication
+try {
+  clusterModel.assign("NOT-EXIST", replica.getPartitionName(), 
replica.getReplicaState(),
+  node.getInstanceName());
+  Assert.fail("Assigning a non existing resource partition shall fail.");
+} catch (HelixException ex) {
+  // expected
+}
+
+// Assign a non-exist replication
+try {
+  clusterModel
+  .assign(replica.getResourceName(), replica.getPartitionName(), 
replica.getReplicaState(),
+  "NON-EXIST");
+  Assert.fail("Assigning a resource partition to a non existing instance 
shall fail.");
+} catch (HelixException ex) {
+  // expected
+}
+
+// Release
+clusterModel
+.release(replica.getResourceName(), replica.getPartitionName(), 
replica.getReplicaState(),
+node.getInstanceName());
+
+
Assert.assertTrue(clusterModel.getContext().getAssignmentForFaultZoneMap().values().stream()
+.allMatch(v -> v.values().stream().allMatch(s -> s.isEmpty(;
 
 Review comment:
   Spell out one letter variables. They don't have to be long, but this is now 
affecting readability. Especially it becomes confusing when nested maps are 
involved.
   
   Lambda expressions exist partly to reduce verbosity of Java but we shouldn't 
sacrifice readability.


[GitHub] [helix] narendly commented on a change in pull request #362: The WAGED rebalancer cluster model implementation

2019-08-02 Thread GitBox
narendly commented on a change in pull request #362: The WAGED rebalancer 
cluster model implementation
URL: https://github.com/apache/helix/pull/362#discussion_r309921368
 
 

 ##
 File path: 
helix-core/src/main/java/org/apache/helix/controller/rebalancer/waged/model/ClusterContext.java
 ##
 @@ -19,9 +19,100 @@
  * under the License.
  */
 
+import org.apache.helix.HelixException;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
+
 /**
- * A placeholder before we have the implementation.
- *
- * This class tracks the global rebalance-related status of a Helix managed 
cluster.
+ * This class tracks the rebalance-related global cluster status.
  */
-public class ClusterContext { }
+public class ClusterContext {
+  private final static float ERROR_MARGIN_FOR_ESTIMATED_MAX_COUNT = 1.1f;
+
+  // This estimation helps to ensure global partition count evenness
+  private final int _estimatedMaxPartitionCount;
+  // This estimation helps to ensure global top state replica count evenness
+  private final int _estimatedMaxTopStateCount;
+  // This estimation helps to ensure per-resource partition count evenness
+  private final Map _estimatedMaxPartitionByResource = new 
HashMap<>();
+
+  // map{zoneName : map{resourceName : set(partitionNames)}}
+  private Map>> _assignmentForFaultZoneMap = 
new HashMap<>();
+
+  /**
+   * Construct the cluster context based on the current instance status.
+   *
+   * @param replicaSetAll the partition replicas that are managed by the 
rebalancer
+   * @param instanceCount The count of all the active instances that can be 
used to host partitions.
+   */
+  ClusterContext(Set replicaSet, int instanceCount) {
+int totalReplicas = 0;
+int totalTopStateReplicas = 0;
+
+for (Map.Entry> entry : replicaSet.stream()
+
.collect(Collectors.groupingBy(AssignableReplica::getResourceName)).entrySet()) 
{
+  int replicas = entry.getValue().size();
+  totalReplicas += replicas;
+
+  int replicaCnt = Math.max(1, estimateAvgReplicaCount(replicas, 
instanceCount));
+  _estimatedMaxPartitionByResource.put(entry.getKey(), replicaCnt);
+
+  totalTopStateReplicas +=
+  
entry.getValue().stream().filter(AssignableReplica::isReplicaTopState).count();
+}
+
+_estimatedMaxPartitionCount = estimateAvgReplicaCount(totalReplicas, 
instanceCount);
+_estimatedMaxTopStateCount = 
estimateAvgReplicaCount(totalTopStateReplicas, instanceCount);
+  }
+
+  public Map>> getAssignmentForFaultZoneMap() {
+return _assignmentForFaultZoneMap;
+  }
+
+  public int getEstimatedMaxPartitionCount() {
+return _estimatedMaxPartitionCount;
+  }
+
+  public int getEstimatedMaxPartitionByResource(String resourceName) {
+return _estimatedMaxPartitionByResource.get(resourceName);
+  }
+
+  public int getEstimatedMaxTopStateCount() {
+return _estimatedMaxTopStateCount;
+  }
+
+  public Set getPartitionsForResourceAndFaultZone(String faultZoneId, 
String resourceName) {
 
 Review comment:
   Minor: Keep the order consistent in both the name and arguments - resource 
and fault zone 


This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
us...@infra.apache.org


With regards,
Apache Git Services


[GitHub] [helix] narendly commented on a change in pull request #362: The WAGED rebalancer cluster model implementation

2019-08-02 Thread GitBox
narendly commented on a change in pull request #362: The WAGED rebalancer 
cluster model implementation
URL: https://github.com/apache/helix/pull/362#discussion_r310213728
 
 

 ##
 File path: 
helix-core/src/test/java/org/apache/helix/controller/rebalancer/waged/model/TestAssignableNode.java
 ##
 @@ -0,0 +1,203 @@
+package org.apache.helix.controller.rebalancer.waged.model;
+
+/*
+ * 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 org.apache.helix.HelixException;
+import 
org.apache.helix.controller.dataproviders.ResourceControllerDataProvider;
+import org.apache.helix.integration.task.TaskTestBase;
+import org.apache.helix.model.BuiltInStateModelDefinitions;
+import org.apache.helix.model.ClusterConfig;
+import org.apache.helix.model.CurrentState;
+import org.apache.helix.model.InstanceConfig;
+import org.apache.helix.model.LiveInstance;
+import org.apache.helix.model.ResourceConfig;
+import org.mockito.Mockito;
+import org.testng.Assert;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import static org.mockito.Mockito.when;
+
+public class TestAssignableNode extends AbstractTestClusterModel {
+  @BeforeClass
+  public void initialize() {
+super.initialize();
+  }
+
+  @Test
+  public void testNormalUsage() throws IOException {
+ResourceControllerDataProvider testCache = setupClusterDataCache();
+Set assignmentSet = generateReplicas(testCache);
+
+// Test 1 - initialization
+
+Set expectedAssignmentSet1 = new 
HashSet<>(_partitionNames.subList(0, 2));
+Set expectedAssignmentSet2 = new 
HashSet<>(_partitionNames.subList(2, 4));
+Map> expectedAssignment = new HashMap<>();
+expectedAssignment.put("Resource1", expectedAssignmentSet1);
+expectedAssignment.put("Resource2", expectedAssignmentSet2);
+Map expectedCapacityMap = new HashMap<>();
+expectedCapacityMap.put("item1", 4);
+expectedCapacityMap.put("item2", 8);
+expectedCapacityMap.put("item3", 30);
+
+
+AssignableNode assignableNode = new AssignableNode(testCache, 
_testInstanceId, assignmentSet);
+
Assert.assertTrue(assignableNode.getCurrentAssignmentsMap().equals(expectedAssignment));
+Assert.assertEquals(assignableNode.getCurrentAssignmentCount(), 4);
+Assert.assertEquals(assignableNode.getHighestCapacityUtilization(), 16.0 / 
20.0, 0.005);
+
Assert.assertTrue(assignableNode.getMaxCapacity().equals(_capacityDataMap));
+Assert.assertEquals(assignableNode.getMaxPartition(), 5);
+Assert.assertEquals(assignableNode.getInstanceTags(), _testInstanceTags);
+Assert.assertEquals(assignableNode.getFaultZone(), _testFaultZoneId);
+
Assert.assertTrue(assignableNode.getDisabledPartitionsMap().equals(_disabledPartitionsMap));
+
Assert.assertTrue(assignableNode.getCurrentCapacity().equals(expectedCapacityMap));
+
+// Test 2 - reduce assignment
+AssignableReplica removingReplica =
+new 
AssignableReplica(testCache.getResourceConfig(_resourceNames.get(1)),
+_partitionNames.get(2), "MASTER", 1);
+
expectedAssignment.get(_resourceNames.get(1)).remove(_partitionNames.get(2));
+expectedCapacityMap.put("item1", 9);
+expectedCapacityMap.put("item2", 18);
+
+assignableNode.release(removingReplica);
+
+
Assert.assertTrue(assignableNode.getCurrentAssignmentsMap().equals(expectedAssignment));
+Assert.assertEquals(assignableNode.getCurrentAssignmentCount(), 3);
+Assert.assertEquals(assignableNode.getHighestCapacityUtilization(), 11.0 / 
20.0, 0.005);
+
Assert.assertTrue(assignableNode.getMaxCapacity().equals(_capacityDataMap));
+Assert.assertEquals(assignableNode.getMaxPartition(), 5);
+Assert.assertEquals(assignableNode.getInstanceTags(), _testInstanceTags);
+Assert.assertEquals(assignableNode.getFaultZone(), _testFaultZoneId);
+
Assert.assertTrue(assignableNode.getDisabledPartitionsMap().equals(_disabledPartitionsMap));
+

[GitHub] [helix] narendly commented on a change in pull request #362: The WAGED rebalancer cluster model implementation

2019-08-02 Thread GitBox
narendly commented on a change in pull request #362: The WAGED rebalancer 
cluster model implementation
URL: https://github.com/apache/helix/pull/362#discussion_r310214870
 
 

 ##
 File path: 
helix-core/src/test/java/org/apache/helix/controller/rebalancer/waged/model/TestAssignableNode.java
 ##
 @@ -0,0 +1,203 @@
+package org.apache.helix.controller.rebalancer.waged.model;
+
+/*
+ * 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 org.apache.helix.HelixException;
+import 
org.apache.helix.controller.dataproviders.ResourceControllerDataProvider;
+import org.apache.helix.integration.task.TaskTestBase;
+import org.apache.helix.model.BuiltInStateModelDefinitions;
+import org.apache.helix.model.ClusterConfig;
+import org.apache.helix.model.CurrentState;
+import org.apache.helix.model.InstanceConfig;
+import org.apache.helix.model.LiveInstance;
+import org.apache.helix.model.ResourceConfig;
+import org.mockito.Mockito;
+import org.testng.Assert;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import static org.mockito.Mockito.when;
+
+public class TestAssignableNode extends AbstractTestClusterModel {
+  @BeforeClass
+  public void initialize() {
+super.initialize();
+  }
+
+  @Test
+  public void testNormalUsage() throws IOException {
+ResourceControllerDataProvider testCache = setupClusterDataCache();
+Set assignmentSet = generateReplicas(testCache);
+
+// Test 1 - initialization
+
+Set expectedAssignmentSet1 = new 
HashSet<>(_partitionNames.subList(0, 2));
+Set expectedAssignmentSet2 = new 
HashSet<>(_partitionNames.subList(2, 4));
+Map> expectedAssignment = new HashMap<>();
+expectedAssignment.put("Resource1", expectedAssignmentSet1);
+expectedAssignment.put("Resource2", expectedAssignmentSet2);
+Map expectedCapacityMap = new HashMap<>();
+expectedCapacityMap.put("item1", 4);
+expectedCapacityMap.put("item2", 8);
+expectedCapacityMap.put("item3", 30);
+
+
+AssignableNode assignableNode = new AssignableNode(testCache, 
_testInstanceId, assignmentSet);
+
Assert.assertTrue(assignableNode.getCurrentAssignmentsMap().equals(expectedAssignment));
+Assert.assertEquals(assignableNode.getCurrentAssignmentCount(), 4);
+Assert.assertEquals(assignableNode.getHighestCapacityUtilization(), 16.0 / 
20.0, 0.005);
+
Assert.assertTrue(assignableNode.getMaxCapacity().equals(_capacityDataMap));
+Assert.assertEquals(assignableNode.getMaxPartition(), 5);
+Assert.assertEquals(assignableNode.getInstanceTags(), _testInstanceTags);
+Assert.assertEquals(assignableNode.getFaultZone(), _testFaultZoneId);
+
Assert.assertTrue(assignableNode.getDisabledPartitionsMap().equals(_disabledPartitionsMap));
+
Assert.assertTrue(assignableNode.getCurrentCapacity().equals(expectedCapacityMap));
+
+// Test 2 - reduce assignment
+AssignableReplica removingReplica =
+new 
AssignableReplica(testCache.getResourceConfig(_resourceNames.get(1)),
+_partitionNames.get(2), "MASTER", 1);
+
expectedAssignment.get(_resourceNames.get(1)).remove(_partitionNames.get(2));
+expectedCapacityMap.put("item1", 9);
+expectedCapacityMap.put("item2", 18);
+
+assignableNode.release(removingReplica);
+
+
Assert.assertTrue(assignableNode.getCurrentAssignmentsMap().equals(expectedAssignment));
+Assert.assertEquals(assignableNode.getCurrentAssignmentCount(), 3);
+Assert.assertEquals(assignableNode.getHighestCapacityUtilization(), 11.0 / 
20.0, 0.005);
+
Assert.assertTrue(assignableNode.getMaxCapacity().equals(_capacityDataMap));
+Assert.assertEquals(assignableNode.getMaxPartition(), 5);
+Assert.assertEquals(assignableNode.getInstanceTags(), _testInstanceTags);
+Assert.assertEquals(assignableNode.getFaultZone(), _testFaultZoneId);
+
Assert.assertTrue(assignableNode.getDisabledPartitionsMap().equals(_disabledPartitionsMap));
+

[GitHub] [helix] narendly commented on a change in pull request #362: The WAGED rebalancer cluster model implementation

2019-08-02 Thread GitBox
narendly commented on a change in pull request #362: The WAGED rebalancer 
cluster model implementation
URL: https://github.com/apache/helix/pull/362#discussion_r309939522
 
 

 ##
 File path: 
helix-core/src/main/java/org/apache/helix/controller/rebalancer/waged/model/ClusterModel.java
 ##
 @@ -19,9 +19,131 @@
  * under the License.
  */
 
+import org.apache.helix.HelixException;
+import org.apache.helix.model.IdealState;
+
+import java.util.Collections;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
+
 /**
- * A placeholder before we have the implementation.
- *
  * This class wraps the required input for the rebalance algorithm.
  */
-public class ClusterModel { }
+public class ClusterModel {
+  private final ClusterContext _clusterContext;
+  // Map to track all the assignable replications. >
+  private final Map> _assignableReplicas;
+  // The index to find the replication information with a certain state. 
>
 
 Review comment:
   Revise this replica key to resource_partition_state? Or we could link the 
method?


This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
us...@infra.apache.org


With regards,
Apache Git Services


[GitHub] [helix] narendly commented on a change in pull request #362: The WAGED rebalancer cluster model implementation

2019-08-02 Thread GitBox
narendly commented on a change in pull request #362: The WAGED rebalancer 
cluster model implementation
URL: https://github.com/apache/helix/pull/362#discussion_r310217077
 
 

 ##
 File path: 
helix-core/src/test/java/org/apache/helix/controller/rebalancer/waged/model/TestClusterContext.java
 ##
 @@ -0,0 +1,93 @@
+package org.apache.helix.controller.rebalancer.waged.model;
+
+/*
+ * 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 org.apache.helix.HelixException;
+import 
org.apache.helix.controller.dataproviders.ResourceControllerDataProvider;
+import org.testng.Assert;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+import java.io.IOException;
+import java.util.Collections;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import static java.util.stream.Collectors.toSet;
 
 Review comment:
   Nit: use Collectors.toSet inline? I don't really care either way but we 
usually don't import static methods?


This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
us...@infra.apache.org


With regards,
Apache Git Services


[GitHub] [helix] narendly commented on a change in pull request #362: The WAGED rebalancer cluster model implementation

2019-08-02 Thread GitBox
narendly commented on a change in pull request #362: The WAGED rebalancer 
cluster model implementation
URL: https://github.com/apache/helix/pull/362#discussion_r310216570
 
 

 ##
 File path: 
helix-core/src/test/java/org/apache/helix/controller/rebalancer/waged/model/TestClusterContext.java
 ##
 @@ -0,0 +1,93 @@
+package org.apache.helix.controller.rebalancer.waged.model;
+
+/*
+ * 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 org.apache.helix.HelixException;
+import 
org.apache.helix.controller.dataproviders.ResourceControllerDataProvider;
+import org.testng.Assert;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+import java.io.IOException;
+import java.util.Collections;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import static java.util.stream.Collectors.toSet;
+
+public class TestClusterContext extends AbstractTestClusterModel {
+  @BeforeClass
+  public void initialize() {
+super.initialize();
+  }
+
+  @Test
+  public void testNormalUsage() throws IOException {
+ResourceControllerDataProvider testCache = setupClusterDataCache();
+Set assignmentSet = generateReplicas(testCache);
+
+// Test 1 - initialization
+ClusterContext context = new ClusterContext(assignmentSet, 2);
+
+// Note that we leaved some margin for the max estimation.
 
 Review comment:
   leaved -> left


This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
us...@infra.apache.org


With regards,
Apache Git Services


[GitHub] [helix] narendly commented on a change in pull request #362: The WAGED rebalancer cluster model implementation

2019-08-02 Thread GitBox
narendly commented on a change in pull request #362: The WAGED rebalancer 
cluster model implementation
URL: https://github.com/apache/helix/pull/362#discussion_r310216339
 
 

 ##
 File path: 
helix-core/src/test/java/org/apache/helix/controller/rebalancer/waged/model/TestAssignableReplica.java
 ##
 @@ -0,0 +1,100 @@
+package org.apache.helix.controller.rebalancer.waged.model;
+
+/*
+ * 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 org.apache.helix.model.ResourceConfig;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import java.io.IOException;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import static org.apache.helix.model.StateModelDefinition.TOP_STATE_PRIORITY;
+
+public class TestAssignableReplica {
+  String resourceName = "Resource";
+  String partitionNamePrefix = "partition";
+  String masterState = "Master";
+  int masterPriority = TOP_STATE_PRIORITY;
+  String slaveState = "Slave";
+  int slavePriority = 2;
+
+  @Test
+  public void testConstructRepliaWithResourceConfig() throws IOException {
+// Init assignable replication with a basic config object
+Map capacityDataMapResource1 = new HashMap<>();
+capacityDataMapResource1.put("item1", 3);
+capacityDataMapResource1.put("item2", 6);
+ResourceConfig testResourceConfigResource = new 
ResourceConfig(resourceName);
+testResourceConfigResource.setPartitionCapacityMap(
+Collections.singletonMap(ResourceConfig.DEFAULT_PARTITION_KEY, 
capacityDataMapResource1));
+
+String partitionName = partitionNamePrefix + 1;
+AssignableReplica replica =
+new AssignableReplica(testResourceConfigResource, partitionName, 
masterState,
+masterPriority);
+Assert.assertEquals(replica.getResourceName(), resourceName);
 
 Review comment:
   Can this series of asserts could be put into a private helper method called 
verifyReplica or something? Too much repeated code?


This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
us...@infra.apache.org


With regards,
Apache Git Services


[GitHub] [helix] narendly commented on a change in pull request #362: The WAGED rebalancer cluster model implementation

2019-08-02 Thread GitBox
narendly commented on a change in pull request #362: The WAGED rebalancer 
cluster model implementation
URL: https://github.com/apache/helix/pull/362#discussion_r310214018
 
 

 ##
 File path: 
helix-core/src/test/java/org/apache/helix/controller/rebalancer/waged/model/TestAssignableNode.java
 ##
 @@ -0,0 +1,203 @@
+package org.apache.helix.controller.rebalancer.waged.model;
+
+/*
+ * 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 org.apache.helix.HelixException;
+import 
org.apache.helix.controller.dataproviders.ResourceControllerDataProvider;
+import org.apache.helix.integration.task.TaskTestBase;
+import org.apache.helix.model.BuiltInStateModelDefinitions;
+import org.apache.helix.model.ClusterConfig;
+import org.apache.helix.model.CurrentState;
+import org.apache.helix.model.InstanceConfig;
+import org.apache.helix.model.LiveInstance;
+import org.apache.helix.model.ResourceConfig;
+import org.mockito.Mockito;
+import org.testng.Assert;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import static org.mockito.Mockito.when;
+
+public class TestAssignableNode extends AbstractTestClusterModel {
+  @BeforeClass
+  public void initialize() {
+super.initialize();
+  }
+
+  @Test
+  public void testNormalUsage() throws IOException {
+ResourceControllerDataProvider testCache = setupClusterDataCache();
+Set assignmentSet = generateReplicas(testCache);
+
+// Test 1 - initialization
+
+Set expectedAssignmentSet1 = new 
HashSet<>(_partitionNames.subList(0, 2));
+Set expectedAssignmentSet2 = new 
HashSet<>(_partitionNames.subList(2, 4));
+Map> expectedAssignment = new HashMap<>();
+expectedAssignment.put("Resource1", expectedAssignmentSet1);
+expectedAssignment.put("Resource2", expectedAssignmentSet2);
+Map expectedCapacityMap = new HashMap<>();
+expectedCapacityMap.put("item1", 4);
+expectedCapacityMap.put("item2", 8);
+expectedCapacityMap.put("item3", 30);
+
+
+AssignableNode assignableNode = new AssignableNode(testCache, 
_testInstanceId, assignmentSet);
+
Assert.assertTrue(assignableNode.getCurrentAssignmentsMap().equals(expectedAssignment));
+Assert.assertEquals(assignableNode.getCurrentAssignmentCount(), 4);
+Assert.assertEquals(assignableNode.getHighestCapacityUtilization(), 16.0 / 
20.0, 0.005);
+
Assert.assertTrue(assignableNode.getMaxCapacity().equals(_capacityDataMap));
+Assert.assertEquals(assignableNode.getMaxPartition(), 5);
+Assert.assertEquals(assignableNode.getInstanceTags(), _testInstanceTags);
+Assert.assertEquals(assignableNode.getFaultZone(), _testFaultZoneId);
+
Assert.assertTrue(assignableNode.getDisabledPartitionsMap().equals(_disabledPartitionsMap));
+
Assert.assertTrue(assignableNode.getCurrentCapacity().equals(expectedCapacityMap));
+
+// Test 2 - reduce assignment
+AssignableReplica removingReplica =
+new 
AssignableReplica(testCache.getResourceConfig(_resourceNames.get(1)),
+_partitionNames.get(2), "MASTER", 1);
+
expectedAssignment.get(_resourceNames.get(1)).remove(_partitionNames.get(2));
+expectedCapacityMap.put("item1", 9);
+expectedCapacityMap.put("item2", 18);
+
+assignableNode.release(removingReplica);
+
+
Assert.assertTrue(assignableNode.getCurrentAssignmentsMap().equals(expectedAssignment));
+Assert.assertEquals(assignableNode.getCurrentAssignmentCount(), 3);
+Assert.assertEquals(assignableNode.getHighestCapacityUtilization(), 11.0 / 
20.0, 0.005);
+
Assert.assertTrue(assignableNode.getMaxCapacity().equals(_capacityDataMap));
+Assert.assertEquals(assignableNode.getMaxPartition(), 5);
+Assert.assertEquals(assignableNode.getInstanceTags(), _testInstanceTags);
+Assert.assertEquals(assignableNode.getFaultZone(), _testFaultZoneId);
+
Assert.assertTrue(assignableNode.getDisabledPartitionsMap().equals(_disabledPartitionsMap));
+

[GitHub] [helix] narendly commented on a change in pull request #362: The WAGED rebalancer cluster model implementation

2019-08-02 Thread GitBox
narendly commented on a change in pull request #362: The WAGED rebalancer 
cluster model implementation
URL: https://github.com/apache/helix/pull/362#discussion_r310162365
 
 

 ##
 File path: 
helix-core/src/main/java/org/apache/helix/controller/rebalancer/waged/model/ClusterModel.java
 ##
 @@ -19,9 +19,131 @@
  * under the License.
  */
 
+import org.apache.helix.HelixException;
+import org.apache.helix.model.IdealState;
+
+import java.util.Collections;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
+
 /**
- * A placeholder before we have the implementation.
- *
  * This class wraps the required input for the rebalance algorithm.
  */
-public class ClusterModel { }
+public class ClusterModel {
+  private final ClusterContext _clusterContext;
+  // Map to track all the assignable replications. >
+  private final Map> _assignableReplicas;
+  // The index to find the replication information with a certain state. 
>
+  // Note that the identical replicas are dedupe in the index.
+  private final Map> 
_assignableReplicaIndex;
+  private final Map _assignableNodeMap;
+
+  // Records about the previous assignment
+  private final Map _baselineAssignment;
+  private final Map _bestPossibleAssignment;
+
+  /**
+   * @param clusterContext The initialized cluster context.
+   * @param assignableReplicas The replications to be assigned.
+   *   Note that the replicas in this list shall 
not be included while initializing the context and assignable nodes.
+   * @param assignableNodesThe active instances.
+   * @param baselineAssignment The recorded baseline assignment.
+   * @param bestPossibleAssignment The current best possible assignment.
+   */
+  ClusterModel(ClusterContext clusterContext, Set 
assignableReplicas,
+  Set assignableNodes, Map 
baselineAssignment,
+  Map bestPossibleAssignment) {
+_clusterContext = clusterContext;
+
+// Save all the to be assigned replication
+_assignableReplicas = assignableReplicas.stream()
 
 Review comment:
   Nit: just to avoid confusion, what do you think about renaming 
assignableReplicas to assignableReplicaMap? That's what you seem to be doing 
assignableNodeMap/assignableNodes.


This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
us...@infra.apache.org


With regards,
Apache Git Services


[GitHub] [helix] narendly commented on a change in pull request #362: The WAGED rebalancer cluster model implementation

2019-08-02 Thread GitBox
narendly commented on a change in pull request #362: The WAGED rebalancer 
cluster model implementation
URL: https://github.com/apache/helix/pull/362#discussion_r310215326
 
 

 ##
 File path: 
helix-core/src/test/java/org/apache/helix/controller/rebalancer/waged/model/TestAssignableReplica.java
 ##
 @@ -0,0 +1,100 @@
+package org.apache.helix.controller.rebalancer.waged.model;
+
+/*
+ * 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 org.apache.helix.model.ResourceConfig;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import java.io.IOException;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import static org.apache.helix.model.StateModelDefinition.TOP_STATE_PRIORITY;
+
+public class TestAssignableReplica {
+  String resourceName = "Resource";
+  String partitionNamePrefix = "partition";
+  String masterState = "Master";
+  int masterPriority = TOP_STATE_PRIORITY;
+  String slaveState = "Slave";
+  int slavePriority = 2;
+
+  @Test
+  public void testConstructRepliaWithResourceConfig() throws IOException {
+// Init assignable replication with a basic config object
 
 Review comment:
   replication -> replica?


This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
us...@infra.apache.org


With regards,
Apache Git Services


[GitHub] [helix] narendly commented on a change in pull request #362: The WAGED rebalancer cluster model implementation

2019-08-02 Thread GitBox
narendly commented on a change in pull request #362: The WAGED rebalancer 
cluster model implementation
URL: https://github.com/apache/helix/pull/362#discussion_r309939616
 
 

 ##
 File path: 
helix-core/src/main/java/org/apache/helix/controller/rebalancer/waged/model/ClusterModel.java
 ##
 @@ -19,9 +19,131 @@
  * under the License.
  */
 
+import org.apache.helix.HelixException;
+import org.apache.helix.model.IdealState;
+
+import java.util.Collections;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
+
 /**
- * A placeholder before we have the implementation.
- *
  * This class wraps the required input for the rebalance algorithm.
  */
-public class ClusterModel { }
+public class ClusterModel {
+  private final ClusterContext _clusterContext;
+  // Map to track all the assignable replications. >
+  private final Map> _assignableReplicas;
+  // The index to find the replication information with a certain state. 
>
+  // Note that the identical replicas are dedupe in the index.
+  private final Map> 
_assignableReplicaIndex;
+  private final Map _assignableNodeMap;
+
+  // Records about the previous assignment
+  private final Map _baselineAssignment;
 
 Review comment:
   What does the string represent?


This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
us...@infra.apache.org


With regards,
Apache Git Services


[GitHub] [helix] narendly commented on issue #362: The WAGED rebalancer cluster model implementation

2019-08-02 Thread GitBox
narendly commented on issue #362: The WAGED rebalancer cluster model 
implementation
URL: https://github.com/apache/helix/pull/362#issuecomment-517781121
 
 
   This is a big PR! I think it would be a good idea to keep the size of PRs 
smaller if possible.


This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
us...@infra.apache.org


With regards,
Apache Git Services


[GitHub] [helix] narendly commented on a change in pull request #362: The WAGED rebalancer cluster model implementation

2019-08-02 Thread GitBox
narendly commented on a change in pull request #362: The WAGED rebalancer 
cluster model implementation
URL: https://github.com/apache/helix/pull/362#discussion_r310221038
 
 

 ##
 File path: 
helix-core/src/test/java/org/apache/helix/controller/rebalancer/waged/model/TestClusterModel.java
 ##
 @@ -0,0 +1,108 @@
+package org.apache.helix.controller.rebalancer.waged.model;
+
+/*
+ * 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 org.apache.helix.HelixException;
+import 
org.apache.helix.controller.dataproviders.ResourceControllerDataProvider;
+import org.testng.Assert;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+import java.io.IOException;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
+public class TestClusterModel extends AbstractTestClusterModel {
+  @BeforeClass
+  public void initialize() {
+super.initialize();
+  }
+
+  Set generateNodes(ResourceControllerDataProvider testCache) {
+Set nodeSet = new HashSet<>();
+testCache.getInstanceConfigMap().values().stream().forEach(config -> 
nodeSet
+.add(new AssignableNode(testCache, config.getInstanceName(), 
Collections.emptyList(;
+return nodeSet;
+  }
+
+  @Test
+  public void testNormalUsage() throws IOException {
+ResourceControllerDataProvider testCache = setupClusterDataCache();
+Set assignableReplicas = generateReplicas(testCache);
+Set assignableNodes = generateNodes(testCache);
+
+// Test 1 - initialization
+ClusterContext context = new ClusterContext(assignableReplicas, 2);
+ClusterModel clusterModel =
+new ClusterModel(context, assignableReplicas, assignableNodes, 
Collections.emptyMap(),
+Collections.emptyMap());
+
+
Assert.assertTrue(clusterModel.getContext().getAssignmentForFaultZoneMap().values().stream()
+.allMatch(v -> v.values().isEmpty()));
+Assert.assertFalse(clusterModel.getAssignableNodes().values().stream()
+.anyMatch(n -> n.getCurrentAssignmentCount() != 0));
+
+// The initialization of the context, node and replication has been tested 
separately. So for
+// cluster model, focus on testing the assignment and release.
+
+// Assign
+AssignableReplica replica = assignableReplicas.iterator().next();
+AssignableNode node = assignableNodes.iterator().next();
+clusterModel
+.assign(replica.getResourceName(), replica.getPartitionName(), 
replica.getReplicaState(),
+node.getInstanceName());
+
+Assert.assertTrue(
+
clusterModel.getContext().getAssignmentForFaultZoneMap().get(node.getFaultZone())
+
.get(replica.getResourceName()).contains(replica.getPartitionName()));
+
Assert.assertTrue(node.getCurrentAssignmentsMap().get(replica.getResourceName())
+.contains(replica.getPartitionName()));
+
+// Assign a non-exist replication
 
 Review comment:
   nonexistent


This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
us...@infra.apache.org


With regards,
Apache Git Services


[GitHub] [helix] narendly commented on a change in pull request #362: The WAGED rebalancer cluster model implementation

2019-08-02 Thread GitBox
narendly commented on a change in pull request #362: The WAGED rebalancer 
cluster model implementation
URL: https://github.com/apache/helix/pull/362#discussion_r310213569
 
 

 ##
 File path: 
helix-core/src/test/java/org/apache/helix/controller/rebalancer/waged/model/TestAssignableNode.java
 ##
 @@ -0,0 +1,203 @@
+package org.apache.helix.controller.rebalancer.waged.model;
+
+/*
+ * 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 org.apache.helix.HelixException;
+import 
org.apache.helix.controller.dataproviders.ResourceControllerDataProvider;
+import org.apache.helix.integration.task.TaskTestBase;
+import org.apache.helix.model.BuiltInStateModelDefinitions;
+import org.apache.helix.model.ClusterConfig;
+import org.apache.helix.model.CurrentState;
+import org.apache.helix.model.InstanceConfig;
+import org.apache.helix.model.LiveInstance;
+import org.apache.helix.model.ResourceConfig;
+import org.mockito.Mockito;
+import org.testng.Assert;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import static org.mockito.Mockito.when;
+
+public class TestAssignableNode extends AbstractTestClusterModel {
+  @BeforeClass
+  public void initialize() {
+super.initialize();
+  }
+
+  @Test
+  public void testNormalUsage() throws IOException {
+ResourceControllerDataProvider testCache = setupClusterDataCache();
+Set assignmentSet = generateReplicas(testCache);
+
+// Test 1 - initialization
+
+Set expectedAssignmentSet1 = new 
HashSet<>(_partitionNames.subList(0, 2));
+Set expectedAssignmentSet2 = new 
HashSet<>(_partitionNames.subList(2, 4));
+Map> expectedAssignment = new HashMap<>();
+expectedAssignment.put("Resource1", expectedAssignmentSet1);
+expectedAssignment.put("Resource2", expectedAssignmentSet2);
+Map expectedCapacityMap = new HashMap<>();
+expectedCapacityMap.put("item1", 4);
+expectedCapacityMap.put("item2", 8);
+expectedCapacityMap.put("item3", 30);
+
+
+AssignableNode assignableNode = new AssignableNode(testCache, 
_testInstanceId, assignmentSet);
+
Assert.assertTrue(assignableNode.getCurrentAssignmentsMap().equals(expectedAssignment));
+Assert.assertEquals(assignableNode.getCurrentAssignmentCount(), 4);
+Assert.assertEquals(assignableNode.getHighestCapacityUtilization(), 16.0 / 
20.0, 0.005);
+
Assert.assertTrue(assignableNode.getMaxCapacity().equals(_capacityDataMap));
+Assert.assertEquals(assignableNode.getMaxPartition(), 5);
+Assert.assertEquals(assignableNode.getInstanceTags(), _testInstanceTags);
+Assert.assertEquals(assignableNode.getFaultZone(), _testFaultZoneId);
+
Assert.assertTrue(assignableNode.getDisabledPartitionsMap().equals(_disabledPartitionsMap));
+
Assert.assertTrue(assignableNode.getCurrentCapacity().equals(expectedCapacityMap));
+
+// Test 2 - reduce assignment
+AssignableReplica removingReplica =
+new 
AssignableReplica(testCache.getResourceConfig(_resourceNames.get(1)),
+_partitionNames.get(2), "MASTER", 1);
+
expectedAssignment.get(_resourceNames.get(1)).remove(_partitionNames.get(2));
+expectedCapacityMap.put("item1", 9);
+expectedCapacityMap.put("item2", 18);
+
+assignableNode.release(removingReplica);
+
+
Assert.assertTrue(assignableNode.getCurrentAssignmentsMap().equals(expectedAssignment));
+Assert.assertEquals(assignableNode.getCurrentAssignmentCount(), 3);
+Assert.assertEquals(assignableNode.getHighestCapacityUtilization(), 11.0 / 
20.0, 0.005);
+
Assert.assertTrue(assignableNode.getMaxCapacity().equals(_capacityDataMap));
+Assert.assertEquals(assignableNode.getMaxPartition(), 5);
+Assert.assertEquals(assignableNode.getInstanceTags(), _testInstanceTags);
+Assert.assertEquals(assignableNode.getFaultZone(), _testFaultZoneId);
+
Assert.assertTrue(assignableNode.getDisabledPartitionsMap().equals(_disabledPartitionsMap));
+

[GitHub] [helix] narendly commented on a change in pull request #362: The WAGED rebalancer cluster model implementation

2019-08-02 Thread GitBox
narendly commented on a change in pull request #362: The WAGED rebalancer 
cluster model implementation
URL: https://github.com/apache/helix/pull/362#discussion_r310218571
 
 

 ##
 File path: 
helix-core/src/test/java/org/apache/helix/controller/rebalancer/waged/model/TestClusterContext.java
 ##
 @@ -0,0 +1,93 @@
+package org.apache.helix.controller.rebalancer.waged.model;
+
+/*
+ * 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 org.apache.helix.HelixException;
+import 
org.apache.helix.controller.dataproviders.ResourceControllerDataProvider;
+import org.testng.Assert;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+import java.io.IOException;
+import java.util.Collections;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import static java.util.stream.Collectors.toSet;
+
+public class TestClusterContext extends AbstractTestClusterModel {
+  @BeforeClass
+  public void initialize() {
+super.initialize();
+  }
+
+  @Test
+  public void testNormalUsage() throws IOException {
+ResourceControllerDataProvider testCache = setupClusterDataCache();
+Set assignmentSet = generateReplicas(testCache);
+
+// Test 1 - initialization
+ClusterContext context = new ClusterContext(assignmentSet, 2);
+
+// Note that we leaved some margin for the max estimation.
+Assert.assertEquals(context.getEstimatedMaxPartitionCount(), 3);
+Assert.assertEquals(context.getEstimatedMaxTopStateCount(), 2);
+Assert.assertEquals(context.getAssignmentForFaultZoneMap(), 
Collections.emptyMap());
+for (String resourceName : _resourceNames) {
+  
Assert.assertEquals(context.getEstimatedMaxPartitionByResource(resourceName), 
2);
+  Assert.assertEquals(
+  context.getPartitionsForResourceAndFaultZone(_testFaultZoneId, 
resourceName),
+  Collections.emptySet());
+}
+
+// Assign
+Map>> expectedFaultZoneMap = Collections
+.singletonMap(_testFaultZoneId, 
assignmentSet.stream().collect(Collectors
+.groupingBy(AssignableReplica::getResourceName,
+Collectors.mapping(AssignableReplica::getPartitionName, 
toSet();
+
+assignmentSet.stream().forEach(r -> context
+.addPartitionToFaultZone(_testFaultZoneId, r.getResourceName(), 
r.getPartitionName()));
+Assert.assertEquals(context.getAssignmentForFaultZoneMap(), 
expectedFaultZoneMap);
+
+// release
+
Assert.assertTrue(expectedFaultZoneMap.get(_testFaultZoneId).get(_resourceNames.get(0))
 
 Review comment:
   Any reason why you're not using `assign` and `release` functions? instead of 
manually removing them from maps?


This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
us...@infra.apache.org


With regards,
Apache Git Services


[GitHub] [helix] narendly commented on a change in pull request #362: The WAGED rebalancer cluster model implementation

2019-08-02 Thread GitBox
narendly commented on a change in pull request #362: The WAGED rebalancer 
cluster model implementation
URL: https://github.com/apache/helix/pull/362#discussion_r310216686
 
 

 ##
 File path: 
helix-core/src/test/java/org/apache/helix/controller/rebalancer/waged/model/TestClusterContext.java
 ##
 @@ -0,0 +1,93 @@
+package org.apache.helix.controller.rebalancer.waged.model;
+
+/*
+ * 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 org.apache.helix.HelixException;
+import 
org.apache.helix.controller.dataproviders.ResourceControllerDataProvider;
+import org.testng.Assert;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+import java.io.IOException;
+import java.util.Collections;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import static java.util.stream.Collectors.toSet;
+
+public class TestClusterContext extends AbstractTestClusterModel {
+  @BeforeClass
+  public void initialize() {
+super.initialize();
+  }
+
+  @Test
+  public void testNormalUsage() throws IOException {
 
 Review comment:
   Add some description about your tests!


This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
us...@infra.apache.org


With regards,
Apache Git Services


[GitHub] [helix] narendly commented on a change in pull request #362: The WAGED rebalancer cluster model implementation

2019-08-02 Thread GitBox
narendly commented on a change in pull request #362: The WAGED rebalancer 
cluster model implementation
URL: https://github.com/apache/helix/pull/362#discussion_r310215210
 
 

 ##
 File path: 
helix-core/src/test/java/org/apache/helix/controller/rebalancer/waged/model/TestAssignableReplica.java
 ##
 @@ -0,0 +1,100 @@
+package org.apache.helix.controller.rebalancer.waged.model;
+
+/*
+ * 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 org.apache.helix.model.ResourceConfig;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import java.io.IOException;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import static org.apache.helix.model.StateModelDefinition.TOP_STATE_PRIORITY;
 
 Review comment:
   Nit: instead of importing this, can't we just do 
StateModelDefinition.TOP_STATE_PRIORITY?


This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
us...@infra.apache.org


With regards,
Apache Git Services


[GitHub] [helix] narendly commented on a change in pull request #362: The WAGED rebalancer cluster model implementation

2019-08-02 Thread GitBox
narendly commented on a change in pull request #362: The WAGED rebalancer 
cluster model implementation
URL: https://github.com/apache/helix/pull/362#discussion_r310213021
 
 

 ##
 File path: 
helix-core/src/test/java/org/apache/helix/controller/rebalancer/waged/model/AbstractTestClusterModel.java
 ##
 @@ -0,0 +1,161 @@
+package org.apache.helix.controller.rebalancer.waged.model;
+
+/*
+ * 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 
org.apache.helix.controller.dataproviders.ResourceControllerDataProvider;
+import org.apache.helix.model.BuiltInStateModelDefinitions;
+import org.apache.helix.model.ClusterConfig;
+import org.apache.helix.model.CurrentState;
+import org.apache.helix.model.InstanceConfig;
+import org.apache.helix.model.LiveInstance;
+import org.apache.helix.model.ResourceConfig;
+import org.mockito.Mockito;
+import org.testng.annotations.BeforeClass;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import static org.mockito.Mockito.when;
+
+public abstract class AbstractTestClusterModel {
+  protected String _testInstanceId;
+  protected List _resourceNames;
+  protected List _partitionNames;
+  protected Map _capacityDataMap;
+  protected Map> _disabledPartitionsMap;
+  protected List _testInstanceTags;
+  protected String _testFaultZoneId;
+
+  @BeforeClass
+  public void initialize() {
+_testInstanceId = "testInstanceId";
+_resourceNames = new ArrayList<>();
+_resourceNames.add("Resource1");
+_resourceNames.add("Resource2");
+_partitionNames = new ArrayList<>();
+_partitionNames.add("Partition1");
+_partitionNames.add("Partition2");
+_partitionNames.add("Partition3");
+_partitionNames.add("Partition4");
+_capacityDataMap = new HashMap<>();
+_capacityDataMap.put("item1", 20);
+_capacityDataMap.put("item2", 40);
+_capacityDataMap.put("item3", 30);
+List disabledPartitions = new ArrayList<>();
+disabledPartitions.add("TestPartition");
+_disabledPartitionsMap = new HashMap<>();
+_disabledPartitionsMap.put("TestResource", disabledPartitions);
+_testInstanceTags = new ArrayList<>();
+_testInstanceTags.add("TestTag");
+_testFaultZoneId = "testZone";
+  }
+
+  protected ResourceControllerDataProvider setupClusterDataCache() throws 
IOException {
+ResourceControllerDataProvider testCache = 
Mockito.mock(ResourceControllerDataProvider.class);
+
+InstanceConfig testInstanceConfig = new InstanceConfig("testInstanceId");
+testInstanceConfig.setInstanceCapacityMap(_capacityDataMap);
+testInstanceConfig.addTag(_testInstanceTags.get(0));
+testInstanceConfig.setInstanceEnabledForPartition("TestResource", 
"TestPartition", false);
+testInstanceConfig.setInstanceEnabled(true);
+testInstanceConfig.setZoneId(_testFaultZoneId);
+Map instanceConfigMap = new HashMap<>();
+instanceConfigMap.put(_testInstanceId, testInstanceConfig);
+when(testCache.getInstanceConfigMap()).thenReturn(instanceConfigMap);
+
+ClusterConfig testClusterConfig = new ClusterConfig("testClusterConfigId");
+testClusterConfig.setMaxPartitionsPerInstance(5);
+testClusterConfig.setDisabledInstances(Collections.emptyMap());
+testClusterConfig.setTopologyAwareEnabled(false);
+when(testCache.getClusterConfig()).thenReturn(testClusterConfig);
+
+LiveInstance testLiveInstance = new LiveInstance(_testInstanceId);
+testLiveInstance.setSessionId("testSessionId");
+Map liveInstanceMap = new HashMap<>();
+liveInstanceMap.put(_testInstanceId, testLiveInstance);
+when(testCache.getLiveInstances()).thenReturn(liveInstanceMap);
+
+CurrentState testCurrentStateResource1 = Mockito.mock(CurrentState.class);
+Map partitionStateMap1 = new HashMap<>();
+partitionStateMap1.put(_partitionNames.get(0), "MASTER");
+partitionStateMap1.put(_partitionNames.get(1), "SLAVE");
+
when(testCurrentStateResource1.getResourceName()).thenReturn(_resourceNames.get(0));
+

[GitHub] [helix] narendly commented on a change in pull request #362: The WAGED rebalancer cluster model implementation

2019-08-02 Thread GitBox
narendly commented on a change in pull request #362: The WAGED rebalancer 
cluster model implementation
URL: https://github.com/apache/helix/pull/362#discussion_r310215940
 
 

 ##
 File path: 
helix-core/src/test/java/org/apache/helix/controller/rebalancer/waged/model/TestAssignableReplica.java
 ##
 @@ -0,0 +1,100 @@
+package org.apache.helix.controller.rebalancer.waged.model;
+
+/*
+ * 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 org.apache.helix.model.ResourceConfig;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import java.io.IOException;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import static org.apache.helix.model.StateModelDefinition.TOP_STATE_PRIORITY;
+
+public class TestAssignableReplica {
+  String resourceName = "Resource";
+  String partitionNamePrefix = "partition";
+  String masterState = "Master";
+  int masterPriority = TOP_STATE_PRIORITY;
+  String slaveState = "Slave";
+  int slavePriority = 2;
+
+  @Test
+  public void testConstructRepliaWithResourceConfig() throws IOException {
+// Init assignable replication with a basic config object
+Map capacityDataMapResource1 = new HashMap<>();
+capacityDataMapResource1.put("item1", 3);
+capacityDataMapResource1.put("item2", 6);
+ResourceConfig testResourceConfigResource = new 
ResourceConfig(resourceName);
+testResourceConfigResource.setPartitionCapacityMap(
+Collections.singletonMap(ResourceConfig.DEFAULT_PARTITION_KEY, 
capacityDataMapResource1));
+
+String partitionName = partitionNamePrefix + 1;
+AssignableReplica replica =
+new AssignableReplica(testResourceConfigResource, partitionName, 
masterState,
+masterPriority);
+Assert.assertEquals(replica.getResourceName(), resourceName);
+Assert.assertEquals(replica.getPartitionName(), partitionName);
+Assert.assertEquals(replica.getReplicaState(), masterState);
+Assert.assertEquals(replica.getStatePriority(), masterPriority);
+Assert.assertTrue(replica.isReplicaTopState());
+Assert.assertEquals(replica.getCapacity(), capacityDataMapResource1);
+Assert.assertEquals(replica.getResourceInstanceGroupTag(), null);
+Assert.assertEquals(replica.getResourceMaxPartitionsPerInstance(), 
Integer.MAX_VALUE);
+
+// Modify the config and initial more replications.
 
 Review comment:
   initial -> initialize
   replications -> replicas


This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
us...@infra.apache.org


With regards,
Apache Git Services


[GitHub] [helix] narendly commented on a change in pull request #362: The WAGED rebalancer cluster model implementation

2019-08-02 Thread GitBox
narendly commented on a change in pull request #362: The WAGED rebalancer 
cluster model implementation
URL: https://github.com/apache/helix/pull/362#discussion_r310161710
 
 

 ##
 File path: 
helix-core/src/main/java/org/apache/helix/controller/rebalancer/waged/model/ClusterModel.java
 ##
 @@ -19,9 +19,131 @@
  * under the License.
  */
 
+import org.apache.helix.HelixException;
+import org.apache.helix.model.IdealState;
+
+import java.util.Collections;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
+
 /**
- * A placeholder before we have the implementation.
- *
  * This class wraps the required input for the rebalance algorithm.
  */
-public class ClusterModel { }
+public class ClusterModel {
+  private final ClusterContext _clusterContext;
+  // Map to track all the assignable replications. >
+  private final Map> _assignableReplicas;
+  // The index to find the replication information with a certain state. 
>
+  // Note that the identical replicas are dedupe in the index.
+  private final Map> 
_assignableReplicaIndex;
+  private final Map _assignableNodeMap;
+
+  // Records about the previous assignment
+  private final Map _baselineAssignment;
+  private final Map _bestPossibleAssignment;
+
+  /**
+   * @param clusterContext The initialized cluster context.
+   * @param assignableReplicas The replications to be assigned.
 
 Review comment:
   replications -> replicas


This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
us...@infra.apache.org


With regards,
Apache Git Services


[GitHub] [helix] narendly commented on a change in pull request #362: The WAGED rebalancer cluster model implementation

2019-08-02 Thread GitBox
narendly commented on a change in pull request #362: The WAGED rebalancer 
cluster model implementation
URL: https://github.com/apache/helix/pull/362#discussion_r310218199
 
 

 ##
 File path: 
helix-core/src/test/java/org/apache/helix/controller/rebalancer/waged/model/TestClusterContext.java
 ##
 @@ -0,0 +1,93 @@
+package org.apache.helix.controller.rebalancer.waged.model;
+
+/*
+ * 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 org.apache.helix.HelixException;
+import 
org.apache.helix.controller.dataproviders.ResourceControllerDataProvider;
+import org.testng.Assert;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+import java.io.IOException;
+import java.util.Collections;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import static java.util.stream.Collectors.toSet;
+
+public class TestClusterContext extends AbstractTestClusterModel {
+  @BeforeClass
+  public void initialize() {
+super.initialize();
+  }
+
+  @Test
+  public void testNormalUsage() throws IOException {
+ResourceControllerDataProvider testCache = setupClusterDataCache();
+Set assignmentSet = generateReplicas(testCache);
+
+// Test 1 - initialization
+ClusterContext context = new ClusterContext(assignmentSet, 2);
+
+// Note that we leaved some margin for the max estimation.
+Assert.assertEquals(context.getEstimatedMaxPartitionCount(), 3);
+Assert.assertEquals(context.getEstimatedMaxTopStateCount(), 2);
+Assert.assertEquals(context.getAssignmentForFaultZoneMap(), 
Collections.emptyMap());
+for (String resourceName : _resourceNames) {
+  
Assert.assertEquals(context.getEstimatedMaxPartitionByResource(resourceName), 
2);
+  Assert.assertEquals(
+  context.getPartitionsForResourceAndFaultZone(_testFaultZoneId, 
resourceName),
+  Collections.emptySet());
+}
+
+// Assign
+Map>> expectedFaultZoneMap = Collections
+.singletonMap(_testFaultZoneId, 
assignmentSet.stream().collect(Collectors
+.groupingBy(AssignableReplica::getResourceName,
+Collectors.mapping(AssignableReplica::getPartitionName, 
toSet();
+
+assignmentSet.stream().forEach(r -> context
 
 Review comment:
   Nit: spell out r -> assignableReplica for readability


This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
us...@infra.apache.org


With regards,
Apache Git Services


[GitHub] [helix] narendly commented on a change in pull request #362: The WAGED rebalancer cluster model implementation

2019-08-02 Thread GitBox
narendly commented on a change in pull request #362: The WAGED rebalancer 
cluster model implementation
URL: https://github.com/apache/helix/pull/362#discussion_r310213353
 
 

 ##
 File path: 
helix-core/src/test/java/org/apache/helix/controller/rebalancer/waged/model/TestAssignableNode.java
 ##
 @@ -0,0 +1,203 @@
+package org.apache.helix.controller.rebalancer.waged.model;
+
+/*
+ * 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 org.apache.helix.HelixException;
+import 
org.apache.helix.controller.dataproviders.ResourceControllerDataProvider;
+import org.apache.helix.integration.task.TaskTestBase;
+import org.apache.helix.model.BuiltInStateModelDefinitions;
+import org.apache.helix.model.ClusterConfig;
+import org.apache.helix.model.CurrentState;
+import org.apache.helix.model.InstanceConfig;
+import org.apache.helix.model.LiveInstance;
+import org.apache.helix.model.ResourceConfig;
+import org.mockito.Mockito;
+import org.testng.Assert;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import static org.mockito.Mockito.when;
+
+public class TestAssignableNode extends AbstractTestClusterModel {
+  @BeforeClass
+  public void initialize() {
+super.initialize();
+  }
+
+  @Test
+  public void testNormalUsage() throws IOException {
+ResourceControllerDataProvider testCache = setupClusterDataCache();
+Set assignmentSet = generateReplicas(testCache);
+
+// Test 1 - initialization
 
 Review comment:
   Explain?


This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
us...@infra.apache.org


With regards,
Apache Git Services


[GitHub] [helix] alirezazamani closed issue #370: Remove unnecessary touch logic when updating ResourceConfig

2019-08-02 Thread GitBox
alirezazamani closed issue #370: Remove unnecessary touch logic when updating 
ResourceConfig
URL: https://github.com/apache/helix/issues/370
 
 
   


This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
us...@infra.apache.org


With regards,
Apache Git Services


helix - Build # 1638 - Still Failing

2019-08-02 Thread Apache Jenkins Server
The Apache Jenkins build system has built helix (build #1638)

Status: Still Failing

Check console output at https://builds.apache.org/job/helix/1638/ to view the 
results.

[GitHub] [helix] dasahcc merged pull request #371: Remove unnecessary touch logic issues that forces triggering Helix pipelines

2019-08-02 Thread GitBox
dasahcc merged pull request #371: Remove unnecessary touch logic issues that 
forces triggering Helix pipelines
URL: https://github.com/apache/helix/pull/371
 
 
   


This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
us...@infra.apache.org


With regards,
Apache Git Services


[GitHub] [helix] alirezazamani commented on issue #371: Remove unnecessary touch logic issues that forces triggering Helix pipelines

2019-08-02 Thread GitBox
alirezazamani commented on issue #371: Remove unnecessary touch logic issues 
that forces triggering Helix pipelines
URL: https://github.com/apache/helix/pull/371#issuecomment-517754322
 
 
   This PR is ready to be merged, approved by @jiajunwang and @narendly.


This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
us...@infra.apache.org


With regards,
Apache Git Services


[GitHub] [helix] alirezazamani commented on issue #371: Remove unnecessary touch logic issues that forces triggering Helix pipelines

2019-08-02 Thread GitBox
alirezazamani commented on issue #371: Remove unnecessary touch logic issues 
that forces triggering Helix pipelines
URL: https://github.com/apache/helix/pull/371#issuecomment-517754114
 
 
   These changes have been covered by tests. I also check it manually and the 
pipeline is triggered.


This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
us...@infra.apache.org


With regards,
Apache Git Services


[GitHub] [helix] narendly commented on a change in pull request #369: Add the workaround fix for assigning partitions when instance weight …

2019-08-02 Thread GitBox
narendly commented on a change in pull request #369: Add the workaround fix for 
assigning partitions when instance weight …
URL: https://github.com/apache/helix/pull/369#discussion_r310154419
 
 

 ##
 File path: 
helix-core/src/main/java/org/apache/helix/controller/rebalancer/strategy/crushMapping/CardDealingAdjustmentAlgorithmV2.java
 ##
 @@ -55,6 +74,27 @@ public CardDealingAdjustmentAlgorithmV2(Topology topology, 
int replica, Mode mod
 }
   }
 
+  // expose internal fields only for testing purpose
 
 Review comment:
   As I mentioned in another PR, one trick you can use is to create a 
MockCardDealingAdjustmentAlgorithmV2 that extends this class and that contains 
these methods. That way you should be able to access all protected fields, and 
use the mock class for unit testing.


This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
us...@infra.apache.org


With regards,
Apache Git Services


[GitHub] [helix] narendly commented on a change in pull request #333: Fix issue when client only sets ANY at cluster level throttle config

2019-08-02 Thread GitBox
narendly commented on a change in pull request #333: Fix issue when client only 
sets ANY at cluster level throttle config
URL: https://github.com/apache/helix/pull/333#discussion_r310153372
 
 

 ##
 File path: 
helix-core/src/main/java/org/apache/helix/controller/stages/StateTransitionThrottleController.java
 ##
 @@ -99,6 +99,21 @@ public StateTransitionThrottleController(Set 
resources, ClusterConfig cl
 }
   }
 
+  // The getter methods are used for debugging and testing purpose
 
 Review comment:
   I am not 100% comfortable with adding methods just for testing/debugging. 
This is a potential vulnerability in scoping. Here's a trick you can do (I have 
done this in some tests):
   
   Instead of adding methods (that shouldn't otherwise be used other than 
testing purposes), create a child class (for example, 
`MockStateTranisitonThrottleController`) that extends this class and just add 
these test/debug methods. That way, in your unit tests, you could use the mock 
class and still utilize these methods that expose internal variables, rather 
than adding methods directly to the main class.
   
   Do you think that would work?


This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
us...@infra.apache.org


With regards,
Apache Git Services


[GitHub] [helix] narendly commented on a change in pull request #333: Fix issue when client only sets ANY at cluster level throttle config

2019-08-02 Thread GitBox
narendly commented on a change in pull request #333: Fix issue when client only 
sets ANY at cluster level throttle config
URL: https://github.com/apache/helix/pull/333#discussion_r310153372
 
 

 ##
 File path: 
helix-core/src/main/java/org/apache/helix/controller/stages/StateTransitionThrottleController.java
 ##
 @@ -99,6 +99,21 @@ public StateTransitionThrottleController(Set 
resources, ClusterConfig cl
 }
   }
 
+  // The getter methods are used for debugging and testing purpose
 
 Review comment:
   I am not 100% comfortable with adding methods just for this purpose. Here's 
a trick you can do (I have done this in some tests):
   
   Instead of adding methods (that shouldn't otherwise be used other than 
testing purposes), create a child class (for example, 
`MockStateTranisitonThrottleController`) that extends this class and just add 
these test/debug methods. That way, in your unit tests, you could use the mock 
class and still utilize these methods that expose internal variables, rather 
than adding methods directly to the main class.
   
   Do you think that would work?


This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
us...@infra.apache.org


With regards,
Apache Git Services


[GitHub] [helix] narendly commented on a change in pull request #333: Fix issue when client only sets ANY at cluster level throttle config

2019-08-02 Thread GitBox
narendly commented on a change in pull request #333: Fix issue when client only 
sets ANY at cluster level throttle config
URL: https://github.com/apache/helix/pull/333#discussion_r310150104
 
 

 ##
 File path: 
helix-core/src/main/java/org/apache/helix/controller/stages/StateTransitionThrottleController.java
 ##
 @@ -208,13 +210,20 @@ protected void 
chargeResource(StateTransitionThrottleConfig.RebalanceType rebala
*/
   protected void chargeInstance(StateTransitionThrottleConfig.RebalanceType 
rebalanceType,
   String instance) {
-if (_pendingTransitionAllowedPerInstance.containsKey(instance)
-&& 
_pendingTransitionAllowedPerInstance.get(instance).containsKey(rebalanceType)) {
-  chargeANYType(_pendingTransitionAllowedPerInstance.get(instance));
-  Long instanceThrottle = 
_pendingTransitionAllowedPerInstance.get(instance).get(rebalanceType);
-  if (instanceThrottle > 0) {
-_pendingTransitionAllowedPerInstance.get(instance).put(rebalanceType, 
instanceThrottle - 1);
-  }
+charge(rebalanceType, 
_pendingTransitionAllowedPerInstance.getOrDefault(instance, new HashMap<>()));
+  }
+
+  private void charge(StateTransitionThrottleConfig.RebalanceType 
rebalanceType,
+  Map quota) {
+if 
(StateTransitionThrottleConfig.RebalanceType.NONE.equals(rebalanceType)) {
+  logger.error("Wrong rebalance type NONE as parameter");
+  return;
+}
+// if ANY type is present, decrement one else do nothing
+quota.computeIfPresent(StateTransitionThrottleConfig.RebalanceType.ANY, 
(key, val) -> Math.max(0, val - 1));
 
 Review comment:
   Sorry, I don't quite understand. Does `(rebalanceType, quota) -> Math.max(0, 
quota - 1)` not work? Are you saying it's not important to make code 
self-descriptive? The whole point is to make it so that it's easier to 
understand for people who are not familiar with what we're doing here?


This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
us...@infra.apache.org


With regards,
Apache Git Services


[GitHub] [helix] narendly commented on a change in pull request #333: Fix issue when client only sets ANY at cluster level throttle config

2019-08-02 Thread GitBox
narendly commented on a change in pull request #333: Fix issue when client only 
sets ANY at cluster level throttle config
URL: https://github.com/apache/helix/pull/333#discussion_r310150588
 
 

 ##
 File path: 
helix-core/src/test/java/org/apache/helix/integration/TestPartitionMovementThrottle.java
 ##
 @@ -279,13 +332,15 @@ public void testResourceThrottleWithDelayRebalancer() {
 Assert.assertTrue(_clusterVerifier.verifyByPolling());
 
 for (String db : _dbs) {
-  validateThrottle(DelayedTransition.getResourcePatitionTransitionTimes(), 
db, 2);
+  int maxInParallel = 
getMaxParallelTransitionCount(DelayedTransition.getResourcePatitionTransitionTimes(),
 db);
+  System.out.println(
+  "MaxInParallel: " + maxInParallel + " maxPendingTransition: " + 2);
+  Assert.assertTrue(maxInParallel <= 2, "Throttle condition does not meet 
for " + db);
 }
   }
 
-  private void validateThrottle(
 
 Review comment:
   @i3wangyi You make a great point. Thanks for clarifying and I believe this 
is the correct thing to do.


This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
us...@infra.apache.org


With regards,
Apache Git Services


[GitHub] [helix] narendly commented on a change in pull request #359: Dynamically change the processor thread name when consuming event

2019-08-02 Thread GitBox
narendly commented on a change in pull request #359: Dynamically change the 
processor thread name when consuming event
URL: https://github.com/apache/helix/pull/359#discussion_r310147891
 
 

 ##
 File path: 
helix-core/src/main/java/org/apache/helix/controller/GenericHelixController.java
 ##
 @@ -1165,7 +1163,11 @@ public void run() {
   + _processorName);
   while (!isInterrupted()) {
 try {
-  handleEvent(_eventBlockingQueue.take(), _cache);
+  ClusterEvent newClusterEvent = _eventBlockingQueue.take();
 
 Review comment:
   I don't think it's too much for the simplicity of the code, but I do think 
that it will be more work for you to make that happen.
   
   I don't know if I follow "And logically, ClusterEvent shouldn't know the 
existence of threadName even queue object".
   
   At any rate, the point still stands - it is always important to minimize the 
amount of objects being created since we need to be conscious of memory 
pressure. If you have other thoughts, please post them here.
   
   I am fine with leaving this item as a **TODO** in the codebase and creating 
a corresponding issue.


This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
us...@infra.apache.org


With regards,
Apache Git Services


[GitHub] [helix] narendly commented on issue #371: Remove unnecessary touch logic issues that forces triggering Helix pipelines

2019-08-02 Thread GitBox
narendly commented on issue #371: Remove unnecessary touch logic issues that 
forces triggering Helix pipelines
URL: https://github.com/apache/helix/pull/371#issuecomment-517712533
 
 
   You could do 
https://github.com/apache/helix/wiki/Pull-Request-Check-In-Steps to get this 
checked in. As discussed offline, take your time to test it out locally :)


This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
us...@infra.apache.org


With regards,
Apache Git Services