[GitHub] [helix] mcvsubbu opened a new issue #377: Multiple problems with 0.9.0

2019-08-05 Thread GitBox
mcvsubbu opened a new issue #377: Multiple problems with 0.9.0
URL: https://github.com/apache/helix/issues/377
 
 
   We see the following issues in Pinot deployment:
   
   1. Controller callback does not happen on a PARTICIPANT helix manager when 
leadership changes.
   2. Other participants that host regular partitions do not get a state 
transition after the situation in previous step happens. The only solution is 
to restart the leader controller.
   3. Task queues are stuck with multiple tasks in IN_PROGRESS state.


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 opened a new pull request #376: Add #batchGetInstancesStoppableChecks to solve performance issue

2019-08-05 Thread GitBox
i3wangyi opened a new pull request #376: Add #batchGetInstancesStoppableChecks 
to solve performance issue
URL: https://github.com/apache/helix/pull/376
 
 
   TODO, will update everything 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 opened a new issue #375: Drop all tasks whose requested state is DROPPED

2019-08-05 Thread GitBox
narendly opened a new issue #375: Drop all tasks whose requested state is 
DROPPED
URL: https://github.com/apache/helix/issues/375
 
 
   Upon a Participant disconnect, the Participant would carry over from the 
last session. This would copy all previous task states to the current session 
and set their requested states as DROPPED (for INIT and RUNNING states). 
   
   It came to our attention that sometimes these Participants experience 
connection issues and the tasks happen to be in TASK_ERROR or COMPLETED states. 
These tasks would get stuck on the Participant and never be dropped. This issue 
proposes to add the logic that would get all tasks whose requested states are 
DROPPED to be dropped immediately.
   
   See: JobDispatcher.java line 441.


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] kaisun2000 commented on issue #365: Fix RoutingTableProvider statePropagationLatency metric reporting bug

2019-08-05 Thread GitBox
kaisun2000 commented on issue #365: Fix RoutingTableProvider 
statePropagationLatency metric reporting bug
URL: https://github.com/apache/helix/pull/365#issuecomment-518453741
 
 
   Resolved all the review request. Also passing the test. Next step is to 
merge into trunk


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] kaisun2000 commented on a change in pull request #365: Fix RoutingTableProvider statePropagationLatency metric reporting bug

2019-08-05 Thread GitBox
kaisun2000 commented on a change in pull request #365: Fix RoutingTableProvider 
statePropagationLatency metric reporting bug
URL: https://github.com/apache/helix/pull/365#discussion_r310841129
 
 

 ##
 File path: 
helix-core/src/test/java/org/apache/helix/common/caches/TestCurrentStateSnapshot.java
 ##
 @@ -0,0 +1,106 @@
+package org.apache.helix.common.caches;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import org.apache.helix.MockAccessor;
+import org.apache.helix.PropertyKey;
+import org.apache.helix.ZNRecord;
+import org.apache.helix.model.CurrentState;
+import org.apache.helix.model.LiveInstance;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+
+/**
+ * Unit test for {@link CurrentStateSnapshot}
+ */
+public class TestCurrentStateSnapshot {
 
 Review comment:
   added.


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] kaisun2000 commented on a change in pull request #365: Fix RoutingTableProvider statePropagationLatency metric reporting bug

2019-08-05 Thread GitBox
kaisun2000 commented on a change in pull request #365: Fix RoutingTableProvider 
statePropagationLatency metric reporting bug
URL: https://github.com/apache/helix/pull/365#discussion_r310838708
 
 

 ##
 File path: 
helix-core/src/main/java/org/apache/helix/spectator/RoutingTableProvider.java
 ##
 @@ -558,23 +558,30 @@ protected void refresh(Map>> curre
 
   private void resetRoutingTableAndNotify(long startTime, RoutingTable 
newRoutingTable) {
 _routingTableRef.set(newRoutingTable);
-logger.info("Refresh the RoutingTable for cluster {}, takes {} ms.",
-(_helixManager != null ? _helixManager.getClusterName() : null),
+String clusterName = _helixManager != null ? 
_helixManager.getClusterName() : null;
+logger.info("Refresh the RoutingTable for cluster {}, takes {} ms.", 
clusterName,
 (System.currentTimeMillis() - startTime));
-notifyRoutingTableChange();
+
+// TODO: move the callback user code logic to separate thread upon routing 
table statePropagation latency
+// integration test result. If the latency is more than 2 secs, we need to 
change this part.
+notifyRoutingTableChange(clusterName);
 
 // Update timestamp for last refresh
 if (_isPeriodicRefreshEnabled) {
   _lastRefreshTimestamp = System.currentTimeMillis();
 }
   }
 
-  private void notifyRoutingTableChange() {
-for (Map.Entry entry : 
_routingTableChangeListenerMap
-.entrySet()) {
-  entry.getKey().onRoutingTableChange(new 
RoutingTableSnapshot(_routingTableRef.get()),
-  entry.getValue().getContext());
+  private void notifyRoutingTableChange(String clusterName) {
+// This call back is called in the main event queue of 
RoutingTableProvider. We add log to record time spent
+// here. Potentially, we should call this callback in a separate thread if 
this is a bottleneck.
+long startTime = System.currentTimeMillis();
+for (Map.Entry entry : 
_routingTableChangeListenerMap.entrySet()) {
+  entry.getKey()
+  .onRoutingTableChange(new 
RoutingTableSnapshot(_routingTableRef.get()), entry.getValue().getContext());
 }
+logger.info("RoutingTableProvider callback [aka not helix time] for 
cluster {}, take {} ms.", clusterName,
 
 Review comment:
   Helix Time == time spent in Helix side. Will change to  
"RoutingTableProvider user callback time"
   
   No. they will not overwhelm the log. One RoutingTableProvider will be 
created by one cluster. The routingTableProvider change will not be that 
frequent, definitely should be a lot less than all the pipeline running log. So 
we should be safe 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] kaisun2000 commented on a change in pull request #365: Fix RoutingTableProvider statePropagationLatency metric reporting bug

2019-08-05 Thread GitBox
kaisun2000 commented on a change in pull request #365: Fix RoutingTableProvider 
statePropagationLatency metric reporting bug
URL: https://github.com/apache/helix/pull/365#discussion_r310838708
 
 

 ##
 File path: 
helix-core/src/main/java/org/apache/helix/spectator/RoutingTableProvider.java
 ##
 @@ -558,23 +558,30 @@ protected void refresh(Map>> curre
 
   private void resetRoutingTableAndNotify(long startTime, RoutingTable 
newRoutingTable) {
 _routingTableRef.set(newRoutingTable);
-logger.info("Refresh the RoutingTable for cluster {}, takes {} ms.",
-(_helixManager != null ? _helixManager.getClusterName() : null),
+String clusterName = _helixManager != null ? 
_helixManager.getClusterName() : null;
+logger.info("Refresh the RoutingTable for cluster {}, takes {} ms.", 
clusterName,
 (System.currentTimeMillis() - startTime));
-notifyRoutingTableChange();
+
+// TODO: move the callback user code logic to separate thread upon routing 
table statePropagation latency
+// integration test result. If the latency is more than 2 secs, we need to 
change this part.
+notifyRoutingTableChange(clusterName);
 
 // Update timestamp for last refresh
 if (_isPeriodicRefreshEnabled) {
   _lastRefreshTimestamp = System.currentTimeMillis();
 }
   }
 
-  private void notifyRoutingTableChange() {
-for (Map.Entry entry : 
_routingTableChangeListenerMap
-.entrySet()) {
-  entry.getKey().onRoutingTableChange(new 
RoutingTableSnapshot(_routingTableRef.get()),
-  entry.getValue().getContext());
+  private void notifyRoutingTableChange(String clusterName) {
+// This call back is called in the main event queue of 
RoutingTableProvider. We add log to record time spent
+// here. Potentially, we should call this callback in a separate thread if 
this is a bottleneck.
+long startTime = System.currentTimeMillis();
+for (Map.Entry entry : 
_routingTableChangeListenerMap.entrySet()) {
+  entry.getKey()
+  .onRoutingTableChange(new 
RoutingTableSnapshot(_routingTableRef.get()), entry.getValue().getContext());
 }
+logger.info("RoutingTableProvider callback [aka not helix time] for 
cluster {}, take {} ms.", clusterName,
 
 Review comment:
   Helix Time == time spent in Helix side. Will change to this term. 
   
   No. they will not overwhelm the log. One RoutingTableProvider will be 
created by one cluster. The routingTableProvider change will not be that 
frequent, definitely should be a lot less than all the pipeline running log. So 
we should be safe 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] dasahcc commented on issue #374: Stablize the REST tests in helix-rest

2019-08-05 Thread GitBox
dasahcc commented on issue #374: Stablize the REST tests in helix-rest
URL: https://github.com/apache/helix/pull/374#issuecomment-518443325
 
 
   > A lot of duplicate prints, can you check testng's BeforeMethod and 
AfterMethod annotations
   > https://dzone.com/articles/testng-aftermethod-annotation
   
   No. I tried that. It is not working. It only shows the "beforeMethod" or 
"afterMethod" name, since you dont have a way to memorize which method it is 
running.


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] dasahcc commented on issue #374: Stablize the REST tests in helix-rest

2019-08-05 Thread GitBox
dasahcc commented on issue #374: Stablize the REST tests in helix-rest
URL: https://github.com/apache/helix/pull/374#issuecomment-518442369
 
 
   > A lot of duplicate prints, can you check testng's BeforeMethod and 
AfterMethod annotations
   > https://dzone.com/articles/testng-aftermethod-annotation
   
   That's a good point. Let me 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] kaisun2000 commented on a change in pull request #365: Fix RoutingTableProvider statePropagationLatency metric reporting bug

2019-08-05 Thread GitBox
kaisun2000 commented on a change in pull request #365: Fix RoutingTableProvider 
statePropagationLatency metric reporting bug
URL: https://github.com/apache/helix/pull/365#discussion_r310832882
 
 

 ##
 File path: 
helix-core/src/main/java/org/apache/helix/spectator/RoutingTableProvider.java
 ##
 @@ -558,23 +558,30 @@ protected void refresh(Map>> curre
 
   private void resetRoutingTableAndNotify(long startTime, RoutingTable 
newRoutingTable) {
 _routingTableRef.set(newRoutingTable);
-logger.info("Refresh the RoutingTable for cluster {}, takes {} ms.",
-(_helixManager != null ? _helixManager.getClusterName() : null),
+String clusterName = _helixManager != null ? 
_helixManager.getClusterName() : null;
+logger.info("Refresh the RoutingTable for cluster {}, takes {} ms.", 
clusterName,
 (System.currentTimeMillis() - startTime));
-notifyRoutingTableChange();
+
+// TODO: move the callback user code logic to separate thread upon routing 
table statePropagation latency
+// integration test result. If the latency is more than 2 secs, we need to 
change this part.
 
 Review comment:
   Yes, storage team is doing integration test and they are blocked by this 
one. 2 sec is perceived number from meeting with them 


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] kaisun2000 commented on a change in pull request #365: Fix RoutingTableProvider statePropagationLatency metric reporting bug

2019-08-05 Thread GitBox
kaisun2000 commented on a change in pull request #365: Fix RoutingTableProvider 
statePropagationLatency metric reporting bug
URL: https://github.com/apache/helix/pull/365#discussion_r310832625
 
 

 ##
 File path: 
helix-core/src/main/java/org/apache/helix/spectator/RoutingTableProvider.java
 ##
 @@ -558,23 +558,30 @@ protected void refresh(Map>> curre
 
   private void resetRoutingTableAndNotify(long startTime, RoutingTable 
newRoutingTable) {
 _routingTableRef.set(newRoutingTable);
-logger.info("Refresh the RoutingTable for cluster {}, takes {} ms.",
-(_helixManager != null ? _helixManager.getClusterName() : null),
+String clusterName = _helixManager != null ? 
_helixManager.getClusterName() : null;
+logger.info("Refresh the RoutingTable for cluster {}, takes {} ms.", 
clusterName,
 
 Review comment:
   changed. 


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] kaisun2000 commented on a change in pull request #365: Fix RoutingTableProvider statePropagationLatency metric reporting bug

2019-08-05 Thread GitBox
kaisun2000 commented on a change in pull request #365: Fix RoutingTableProvider 
statePropagationLatency metric reporting bug
URL: https://github.com/apache/helix/pull/365#discussion_r310832401
 
 

 ##
 File path: 
helix-core/src/main/java/org/apache/helix/spectator/RoutingTableProvider.java
 ##
 @@ -558,23 +558,30 @@ protected void refresh(Map>> curre
 
   private void resetRoutingTableAndNotify(long startTime, RoutingTable 
newRoutingTable) {
 _routingTableRef.set(newRoutingTable);
-logger.info("Refresh the RoutingTable for cluster {}, takes {} ms.",
-(_helixManager != null ? _helixManager.getClusterName() : null),
+String clusterName = _helixManager != null ? 
_helixManager.getClusterName() : null;
 
 Review comment:
   The code is always like this, maybe for the reason that some traditional 
deployment code can indeed have helixManager to be null and people don't want 
them to fail. I guess the most immediate previous change in the piece of code 
was from you and it was still kept this way. So let us just keep it this way. 


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] kaisun2000 commented on a change in pull request #365: Fix RoutingTableProvider statePropagationLatency metric reporting bug

2019-08-05 Thread GitBox
kaisun2000 commented on a change in pull request #365: Fix RoutingTableProvider 
statePropagationLatency metric reporting bug
URL: https://github.com/apache/helix/pull/365#discussion_r310831810
 
 

 ##
 File path: 
helix-core/src/main/java/org/apache/helix/common/caches/AbstractDataCache.java
 ##
 @@ -48,15 +50,17 @@ public AbstractDataCache(ControlContextProvider 
controlContextProvider) {
* Selectively fetch Helix Properties from ZK by comparing the version of 
local cached one with the one on ZK.
* If version on ZK is newer, fetch it from zk and update local cache.
* @param accessor the HelixDataAccessor
-   * @param reloadKeys keys needs to be reload
+   * @param reloadKeysIn keys needs to be reload
 
 Review comment:
   ReloadKeysIn means this is the input parameter, it is not changed
   Note, later, there is a reloadedKeys, that is the output parameter with all 
the keys that are reloaded. 


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] dasahcc opened a new pull request #374: Stablize the REST tests in helix-rest

2019-08-05 Thread GitBox
dasahcc opened a new pull request #374: Stablize the REST tests in helix-rest
URL: https://github.com/apache/helix/pull/374
 
 
   ### Issues
   
   For test stabilizing, not create an issue.
   
   ### Description
   
   - [ ] Here are some details about my PR, including screenshots of any UI 
changes:
   
   Stablize the REST tests by following changes:
   1. Remove temporary cluster which impact the ClusterAccessor test
   2. Add all start/end message for test debug purpose.
   3. Disable unstable monitoring test for default MBeans. Sometimes we can 
query it sometimes not. It is not critical test path. Let's make it stable 
later.
   
   ### Tests
   mvn test
   
   [INFO] Tests run: 83, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 
35.442 s - in TestSuite
   [INFO] 
   [INFO] Results:
   [INFO] 
   [INFO] Tests run: 83, Failures: 0, Errors: 0, Skipped: 0
   [INFO] 
   [INFO] 

   [INFO] BUILD SUCCESS
   [INFO] 

   [INFO] Total time: 42.434 s
   [INFO] Finished at: 2019-08-05T16:23:01-07:00
   [INFO] Final Memory: 42M/1215M
   [INFO] 

   
   


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 issue #367: Add transient cache for CustomRestClient implementation

2019-08-05 Thread GitBox
i3wangyi commented on issue #367: Add transient cache for CustomRestClient 
implementation
URL: https://github.com/apache/helix/pull/367#issuecomment-518406925
 
 
   > > > The parallel request still need to be considered. Say you are 
implementing the locking by keys. We need 100 participants partition level 
status called from single instance health check. Then you will read one 
instance partition level status after the other. It is still sequential read.
   > > 
   > > 
   > > The sequential read comes from how the upper class uses the 
CustomRestClientImpl. Currently, it is sequential but it's the scope of next 
PR. In this PR, my purpose is to add the cache implementation so we can change 
the implementation of the upper class (ServiceImpl) and make it parallel.
   > 
   > We need to think about it as a whole piece. I can image that you parallel 
the requests by using thread pool for each key. But in that case, you may end 
up with have multiple idling threads hanging there because of locking on the 
same key.
   
   From the decouple point of view, the PR focuses on CustomRestClient's change 
and its responsibility IMO is to ensure the same request won't get called 
twice. It's the upper class' job to make the right parallel requests and I'm 
planning to address it later in the next PR piece by piece. Is your idea to 
dedupe the # of threads based on requests, in that case, the dedupe logic needs 
to be handled in the upper layer.


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] dasahcc commented on issue #367: Add transient cache for CustomRestClient implementation

2019-08-05 Thread GitBox
dasahcc commented on issue #367: Add transient cache for CustomRestClient 
implementation
URL: https://github.com/apache/helix/pull/367#issuecomment-518402635
 
 
   > > The parallel request still need to be considered. Say you are 
implementing the locking by keys. We need 100 participants partition level 
status called from single instance health check. Then you will read one 
instance partition level status after the other. It is still sequential read.
   > 
   > The sequential read comes from how the upper class uses the 
CustomRestClientImpl. Currently, it is sequential but it's the scope of next 
PR. In this PR, my purpose is to add the cache implementation so we can change 
the implementation of the upper class (ServiceImpl) and make it parallel.
   
   We need to think about it as a whole piece. I can image that you parallel 
the requests by using thread pool for each key. But in that case, you may end 
up with have multiple idling threads hanging there because of locking on same 
key.


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 issue #367: Add transient cache for CustomRestClient implementation

2019-08-05 Thread GitBox
i3wangyi commented on issue #367: Add transient cache for CustomRestClient 
implementation
URL: https://github.com/apache/helix/pull/367#issuecomment-518397174
 
 
   > The parallel request still need to be considered. Say you are implementing 
the locking by keys. We need 100 participants partition level status called 
from single instance health check. Then you will read one instance partition 
level status after the other. It is still sequential read.
   
   The sequential read comes from how the upper class uses the 
CustomRestClientImpl. Currently, it is sequential but it's the scope of next 
PR. In this PR, my purpose is to add the cache implementation so we can change 
the implementation of the upper class (ServiceImpl) and make it parallel.


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 #367: Add transient cache for CustomRestClient implementation

2019-08-05 Thread GitBox
i3wangyi commented on a change in pull request #367: Add transient cache for 
CustomRestClient implementation
URL: https://github.com/apache/helix/pull/367#discussion_r310786737
 
 

 ##
 File path: 
helix-rest/src/main/java/org/apache/helix/rest/client/CustomRestClientImpl.java
 ##
 @@ -97,7 +106,43 @@ public CustomRestClientImpl(HttpClient httpClient) {
   kv -> result.put(kv.getKey(), 
kv.getValue().get(IS_HEALTHY_FIELD).asBoolean()));
   return result;
 };
-return handleResponse(post(url, payLoads), jsonConverter);
+String requestId = baseUrl + customPayloads.toString() + 
partitions.toString();
+try {
+  lock(requestId);
+  if (_cachedResults.containsKey(requestId)) {
+return _cachedResults.get(requestId);
+  }
+  Map result = handleResponse(post(url, payLoads), 
jsonConverter);
+  _cachedResults.put(requestId, result);
+  return result;
+} catch (InterruptedException e) {
+  e.printStackTrace();
+} finally {
+  unlock(requestId);
+}
+return Collections.emptyMap();
+  }
+
+  @VisibleForTesting
+  Map> getCachedResults() {
+return _cachedResults;
+  }
+
+  private void lock(String key) throws InterruptedException {
+synchronized (lockedKeys) {
 
 Review comment:
   It is locked on key level,  my unit test just verifies it. See the below 
debug message, other thread is able to acquire a different key before others 
release the key
   ```
   Thread: 7 acquired key http://localhost:1000{}[Thread: 7]
   Thread: 4 acquired key http://localhost:1000{}[Thread: 4]
   Thread: 6 acquired key http://localhost:1000{}[Thread: 6]
   Thread: 0 acquired key http://localhost:1000{}[Thread: 0]
   Thread: 9 acquired key http://localhost:1000{}[Thread: 9]
   Thread: 5 acquired key http://localhost:1000{}[Thread: 5]
   Thread: 2 acquired key http://localhost:1000{}[Thread: 2]
   Thread: 8 acquired key http://localhost:1000{}[Thread: 8]
   Thread: 3 acquired key http://localhost:1000{}[Thread: 3]
   Thread: 1 acquired key http://localhost:1000{}[Thread: 1]
   Thread: 4 release lock for http://localhost:1000{}[Thread: 4]
   Thread: 9 release lock for http://localhost:1000{}[Thread: 9]
   Thread: 2 release lock for http://localhost:1000{}[Thread: 2]
   Thread: 1 release lock for http://localhost:1000{}[Thread: 1]
   Thread: 6 release lock for http://localhost:1000{}[Thread: 6]
   Thread: 0 release lock for http://localhost:1000{}[Thread: 0]
   Thread: 3 release lock for http://localhost:1000{}[Thread: 3]
   Thread: 8 release lock for http://localhost:1000{}[Thread: 8]
   Thread: 7 release lock for http://localhost:1000{}[Thread: 7]
   Thread: 5 release lock for http://localhost:1000{}[Thread: 5]
   ```


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] dasahcc commented on issue #367: Add transient cache for CustomRestClient implementation

2019-08-05 Thread GitBox
dasahcc commented on issue #367: Add transient cache for CustomRestClient 
implementation
URL: https://github.com/apache/helix/pull/367#issuecomment-518390345
 
 
   The parallel request still need to be considered. Say you are implementing 
the locking by keys. We need 100 participants partition level status called 
from single instance health check. Then you will read one instance partition 
level status after the other. It is still sequential read. 


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] dasahcc merged pull request #359: Dynamically change the processor thread name when consuming event

2019-08-05 Thread GitBox
dasahcc merged pull request #359: Dynamically change the processor thread name 
when consuming event
URL: https://github.com/apache/helix/pull/359
 
 
   


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 issue #359: Dynamically change the processor thread name when consuming event

2019-08-05 Thread GitBox
i3wangyi commented on issue #359: Dynamically change the processor thread name 
when consuming event
URL: https://github.com/apache/helix/pull/359#issuecomment-518348999
 
 
   This PR is ready to be merged, approved by @lei-xia 


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] dasahcc commented on a change in pull request #367: Add transient cache for CustomRestClient implementation

2019-08-05 Thread GitBox
dasahcc commented on a change in pull request #367: Add transient cache for 
CustomRestClient implementation
URL: https://github.com/apache/helix/pull/367#discussion_r310212588
 
 

 ##
 File path: 
helix-rest/src/main/java/org/apache/helix/rest/client/CustomRestClientImpl.java
 ##
 @@ -97,7 +106,43 @@ public CustomRestClientImpl(HttpClient httpClient) {
   kv -> result.put(kv.getKey(), 
kv.getValue().get(IS_HEALTHY_FIELD).asBoolean()));
   return result;
 };
-return handleResponse(post(url, payLoads), jsonConverter);
+String requestId = baseUrl + customPayloads.toString() + 
partitions.toString();
+try {
+  lock(requestId);
+  if (_cachedResults.containsKey(requestId)) {
+return _cachedResults.get(requestId);
+  }
+  Map result = handleResponse(post(url, payLoads), 
jsonConverter);
+  _cachedResults.put(requestId, result);
+  return result;
+} catch (InterruptedException e) {
+  e.printStackTrace();
 
 Review comment:
   Why not use log but print out?


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] dasahcc commented on a change in pull request #367: Add transient cache for CustomRestClient implementation

2019-08-05 Thread GitBox
dasahcc commented on a change in pull request #367: Add transient cache for 
CustomRestClient implementation
URL: https://github.com/apache/helix/pull/367#discussion_r310212407
 
 

 ##
 File path: 
helix-rest/src/main/java/org/apache/helix/rest/client/CustomRestClientImpl.java
 ##
 @@ -97,7 +106,43 @@ public CustomRestClientImpl(HttpClient httpClient) {
   kv -> result.put(kv.getKey(), 
kv.getValue().get(IS_HEALTHY_FIELD).asBoolean()));
   return result;
 };
-return handleResponse(post(url, payLoads), jsonConverter);
+String requestId = baseUrl + customPayloads.toString() + 
partitions.toString();
+try {
+  lock(requestId);
+  if (_cachedResults.containsKey(requestId)) {
+return _cachedResults.get(requestId);
+  }
+  Map result = handleResponse(post(url, payLoads), 
jsonConverter);
+  _cachedResults.put(requestId, result);
+  return result;
+} catch (InterruptedException e) {
+  e.printStackTrace();
+} finally {
+  unlock(requestId);
+}
+return Collections.emptyMap();
+  }
+
+  @VisibleForTesting
+  Map> getCachedResults() {
+return _cachedResults;
+  }
+
+  private void lock(String key) throws InterruptedException {
+synchronized (lockedKeys) {
 
 Review comment:
   This is not locking on key level but set object level.


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 closed issue #358: removing DEFAULT_VIEW_CLUSTER_REFRESH_PERIOD from clusterconfig

2019-08-05 Thread GitBox
narendly closed issue #358: removing DEFAULT_VIEW_CLUSTER_REFRESH_PERIOD from 
clusterconfig
URL: https://github.com/apache/helix/issues/358
 
 
   


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 merged pull request #373: Remove DEFAULT_VIEW_CLUSTER_REFRESH_PERIOD from ClusterConfig #358

2019-08-05 Thread GitBox
narendly merged pull request #373: Remove DEFAULT_VIEW_CLUSTER_REFRESH_PERIOD 
from ClusterConfig #358
URL: https://github.com/apache/helix/pull/373
 
 
   


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 #373: Remove DEFAULT_VIEW_CLUSTER_REFRESH_PERIOD from ClusterConfig #358

2019-08-05 Thread GitBox
narendly commented on issue #373: Remove DEFAULT_VIEW_CLUSTER_REFRESH_PERIOD 
from ClusterConfig #358
URL: https://github.com/apache/helix/pull/373#issuecomment-518325951
 
 
   This PR is ready to be merged, approved by @alirezazamani 


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 opened a new pull request #373: Remove DEFAULT_VIEW_CLUSTER_REFRESH_PERIOD from ClusterConfig #358

2019-08-05 Thread GitBox
narendly opened a new pull request #373: Remove 
DEFAULT_VIEW_CLUSTER_REFRESH_PERIOD from ClusterConfig #358
URL: https://github.com/apache/helix/pull/373
 
 
   ### Issues
   
   - [x] My PR addresses the following Helix issues and references them in the 
PR title:
   
   #358 
   
   ### Description
   
   - [x] Here are some details about my PR, including screenshots of any UI 
changes:
   
   DEFAULT_VIEW_CLUSTER_REFRESH_PERIOD is a constant field for View Aggregator. 
Since this component was removed from the master branch, this constant field 
should be removed as well.
   
   ### Tests
   
   No tests were written/run because this is just removal of an unused constant.
   
   ### Commits
   
   - [x] My commits all reference appropriate Apache Helix GitHub issues in 
their subject lines, and I have squashed multiple commits if they address the 
same issue. In addition, my commits follow the guidelines from "[How to write a 
good git commit message](http://chris.beams.io/posts/git-commit/)":
 1. Subject is separated from body by a blank line
 1. Subject is limited to 50 characters (not including Jira issue reference)
 1. Subject does not end with a period
 1. Subject uses the imperative mood ("add", not "adding")
 1. Body wraps at 72 characters
 1. Body explains "what" and "why", not "how"
   
   ### Code Quality
   
   - [x] My diff has been formatted using helix-style.xml


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 #365: Fix RoutingTableProvider statePropagationLatency metric reporting bug

2019-08-05 Thread GitBox
narendly commented on a change in pull request #365: Fix RoutingTableProvider 
statePropagationLatency metric reporting bug
URL: https://github.com/apache/helix/pull/365#discussion_r310622237
 
 

 ##
 File path: 
helix-core/src/main/java/org/apache/helix/spectator/RoutingTableProvider.java
 ##
 @@ -558,23 +558,30 @@ protected void refresh(Map>> curre
 
   private void resetRoutingTableAndNotify(long startTime, RoutingTable 
newRoutingTable) {
 _routingTableRef.set(newRoutingTable);
-logger.info("Refresh the RoutingTable for cluster {}, takes {} ms.",
-(_helixManager != null ? _helixManager.getClusterName() : null),
+String clusterName = _helixManager != null ? 
_helixManager.getClusterName() : null;
+logger.info("Refresh the RoutingTable for cluster {}, takes {} ms.", 
clusterName,
 
 Review comment:
   Refresh -> refreshed, takes -> took. Generally shouldn't change the logs but 
we're changing it here anyways..


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 #365: Fix RoutingTableProvider statePropagationLatency metric reporting bug

2019-08-05 Thread GitBox
narendly commented on a change in pull request #365: Fix RoutingTableProvider 
statePropagationLatency metric reporting bug
URL: https://github.com/apache/helix/pull/365#discussion_r310619356
 
 

 ##
 File path: 
helix-core/src/main/java/org/apache/helix/common/caches/AbstractDataCache.java
 ##
 @@ -48,15 +50,17 @@ public AbstractDataCache(ControlContextProvider 
controlContextProvider) {
* Selectively fetch Helix Properties from ZK by comparing the version of 
local cached one with the one on ZK.
* If version on ZK is newer, fetch it from zk and update local cache.
* @param accessor the HelixDataAccessor
-   * @param reloadKeys keys needs to be reload
+   * @param reloadKeysIn keys needs to be reload
 
 Review comment:
   reload -> reloaded


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 #365: Fix RoutingTableProvider statePropagationLatency metric reporting bug

2019-08-05 Thread GitBox
narendly commented on a change in pull request #365: Fix RoutingTableProvider 
statePropagationLatency metric reporting bug
URL: https://github.com/apache/helix/pull/365#discussion_r310624803
 
 

 ##
 File path: 
helix-core/src/test/java/org/apache/helix/common/caches/TestCurrentStateSnapshot.java
 ##
 @@ -0,0 +1,106 @@
+package org.apache.helix.common.caches;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import org.apache.helix.MockAccessor;
+import org.apache.helix.PropertyKey;
+import org.apache.helix.ZNRecord;
+import org.apache.helix.model.CurrentState;
+import org.apache.helix.model.LiveInstance;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+
+/**
+ * Unit test for {@link CurrentStateSnapshot}
+ */
+public class TestCurrentStateSnapshot {
 
 Review comment:
   Please add some more description on why this test is needed and what it's 
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 #365: Fix RoutingTableProvider statePropagationLatency metric reporting bug

2019-08-05 Thread GitBox
narendly commented on a change in pull request #365: Fix RoutingTableProvider 
statePropagationLatency metric reporting bug
URL: https://github.com/apache/helix/pull/365#discussion_r310621901
 
 

 ##
 File path: 
helix-core/src/main/java/org/apache/helix/spectator/RoutingTableProvider.java
 ##
 @@ -558,23 +558,30 @@ protected void refresh(Map>> curre
 
   private void resetRoutingTableAndNotify(long startTime, RoutingTable 
newRoutingTable) {
 _routingTableRef.set(newRoutingTable);
-logger.info("Refresh the RoutingTable for cluster {}, takes {} ms.",
-(_helixManager != null ? _helixManager.getClusterName() : null),
+String clusterName = _helixManager != null ? 
_helixManager.getClusterName() : null;
 
 Review comment:
   Should we print out a different log entirely if helixManager is null and 
return? Since it signals a bigger problem?


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 #365: Fix RoutingTableProvider statePropagationLatency metric reporting bug

2019-08-05 Thread GitBox
narendly commented on a change in pull request #365: Fix RoutingTableProvider 
statePropagationLatency metric reporting bug
URL: https://github.com/apache/helix/pull/365#discussion_r310623149
 
 

 ##
 File path: 
helix-core/src/main/java/org/apache/helix/spectator/RoutingTableProvider.java
 ##
 @@ -558,23 +558,30 @@ protected void refresh(Map>> curre
 
   private void resetRoutingTableAndNotify(long startTime, RoutingTable 
newRoutingTable) {
 _routingTableRef.set(newRoutingTable);
-logger.info("Refresh the RoutingTable for cluster {}, takes {} ms.",
-(_helixManager != null ? _helixManager.getClusterName() : null),
+String clusterName = _helixManager != null ? 
_helixManager.getClusterName() : null;
+logger.info("Refresh the RoutingTable for cluster {}, takes {} ms.", 
clusterName,
 (System.currentTimeMillis() - startTime));
-notifyRoutingTableChange();
+
+// TODO: move the callback user code logic to separate thread upon routing 
table statePropagation latency
+// integration test result. If the latency is more than 2 secs, we need to 
change this part.
 
 Review comment:
   Question: Which test are you specifically referring to? Do we have an 
integration test that fails when the latency exceeds 2 secs? Is 2 secs an 
arbitrary number? 


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 #365: Fix RoutingTableProvider statePropagationLatency metric reporting bug

2019-08-05 Thread GitBox
narendly commented on a change in pull request #365: Fix RoutingTableProvider 
statePropagationLatency metric reporting bug
URL: https://github.com/apache/helix/pull/365#discussion_r310623904
 
 

 ##
 File path: 
helix-core/src/main/java/org/apache/helix/spectator/RoutingTableProvider.java
 ##
 @@ -558,23 +558,30 @@ protected void refresh(Map>> curre
 
   private void resetRoutingTableAndNotify(long startTime, RoutingTable 
newRoutingTable) {
 _routingTableRef.set(newRoutingTable);
-logger.info("Refresh the RoutingTable for cluster {}, takes {} ms.",
-(_helixManager != null ? _helixManager.getClusterName() : null),
+String clusterName = _helixManager != null ? 
_helixManager.getClusterName() : null;
+logger.info("Refresh the RoutingTable for cluster {}, takes {} ms.", 
clusterName,
 (System.currentTimeMillis() - startTime));
-notifyRoutingTableChange();
+
+// TODO: move the callback user code logic to separate thread upon routing 
table statePropagation latency
+// integration test result. If the latency is more than 2 secs, we need to 
change this part.
+notifyRoutingTableChange(clusterName);
 
 // Update timestamp for last refresh
 if (_isPeriodicRefreshEnabled) {
   _lastRefreshTimestamp = System.currentTimeMillis();
 }
   }
 
-  private void notifyRoutingTableChange() {
-for (Map.Entry entry : 
_routingTableChangeListenerMap
-.entrySet()) {
-  entry.getKey().onRoutingTableChange(new 
RoutingTableSnapshot(_routingTableRef.get()),
-  entry.getValue().getContext());
+  private void notifyRoutingTableChange(String clusterName) {
+// This call back is called in the main event queue of 
RoutingTableProvider. We add log to record time spent
+// here. Potentially, we should call this callback in a separate thread if 
this is a bottleneck.
+long startTime = System.currentTimeMillis();
+for (Map.Entry entry : 
_routingTableChangeListenerMap.entrySet()) {
+  entry.getKey()
+  .onRoutingTableChange(new 
RoutingTableSnapshot(_routingTableRef.get()), entry.getValue().getContext());
 }
+logger.info("RoutingTableProvider callback [aka not helix time] for 
cluster {}, take {} ms.", clusterName,
 
 Review comment:
   Would this possibly overwhelm the log? And what do you mean by `[aka not 
helix time]`? Let's clarify the terminology here?
   
   take -> took
   
   This log message in general isn't very intuitive.


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 #369: Add the workaround fix for assigning partitions when instance weight …

2019-08-05 Thread GitBox
jiajunwang commented on issue #369: Add the workaround fix for assigning 
partitions when instance weight …
URL: https://github.com/apache/helix/pull/369#issuecomment-518101703
 
 
   I just notice the title, this is not a workaround. Please remove this to 
avoid confusion.


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 #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));
+

[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


  1   2   3   4   5   6   7   >