You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hbase.apache.org by gi...@apache.org on 2021/09/25 20:17:25 UTC

[hbase-site] branch asf-site updated: Published site at 2b26dfbaf47f64e45aef6627b248c3327f5b9a3a.

This is an automated email from the ASF dual-hosted git repository.

git-site-role pushed a commit to branch asf-site
in repository https://gitbox.apache.org/repos/asf/hbase-site.git


The following commit(s) were added to refs/heads/asf-site by this push:
     new 9701af5  Published site at 2b26dfbaf47f64e45aef6627b248c3327f5b9a3a.
9701af5 is described below

commit 9701af5245cbb41453cbe136602e6fb8f86b374a
Author: jenkins <bu...@apache.org>
AuthorDate: Sat Sep 25 20:17:15 2021 +0000

    Published site at 2b26dfbaf47f64e45aef6627b248c3327f5b9a3a.
---
 acid-semantics.html                                |    2 +-
 apache_hbase_reference_guide.pdf                   |    4 +-
 book.html                                          |    2 +-
 bulk-loads.html                                    |    2 +-
 checkstyle-aggregate.html                          |   18 +-
 coc.html                                           |    2 +-
 dependencies.html                                  |    2 +-
 dependency-convergence.html                        |    6 +-
 dependency-info.html                               |    2 +-
 dependency-management.html                         |    2 +-
 devapidocs/index-all.html                          |   30 +-
 .../apache/hadoop/hbase/backup/package-tree.html   |    4 +-
 .../apache/hadoop/hbase/client/package-tree.html   |   28 +-
 .../hadoop/hbase/coprocessor/package-tree.html     |    2 +-
 .../apache/hadoop/hbase/filter/package-tree.html   |    8 +-
 .../hadoop/hbase/hbtop/field/package-tree.html     |    2 +-
 .../hadoop/hbase/hbtop/terminal/package-tree.html  |    2 +-
 .../org/apache/hadoop/hbase/http/package-tree.html |    2 +-
 .../apache/hadoop/hbase/io/hfile/package-tree.html |    4 +-
 .../org/apache/hadoop/hbase/ipc/package-tree.html  |    4 +-
 .../hadoop/hbase/mapreduce/package-tree.html       |    2 +-
 .../hbase/master/assignment/package-tree.html      |    2 +-
 .../BalancerClusterState.DefaultRackManager.html   |    6 +-
 .../BalancerClusterState.LocalityType.html         |    6 +-
 .../master/balancer/BalancerClusterState.html      |  359 +++--
 .../balancer/RegionReplicaCandidateGenerator.html  |   18 +-
 .../RegionReplicaGroupingCostFunction.html         |   26 +-
 .../balancer/RegionReplicaHostCostFunction.html    |   28 +-
 .../RegionReplicaRackCandidateGenerator.html       |    2 +-
 .../balancer/RegionReplicaRackCostFunction.html    |    2 +-
 .../hadoop/hbase/master/balancer/package-tree.html |    2 +-
 .../apache/hadoop/hbase/master/package-tree.html   |    4 +-
 .../hadoop/hbase/monitoring/package-tree.html      |    2 +-
 .../org/apache/hadoop/hbase/package-tree.html      |   16 +-
 .../hadoop/hbase/procedure2/package-tree.html      |    6 +-
 .../hbase/procedure2/store/wal/package-tree.html   |    2 +-
 .../apache/hadoop/hbase/quotas/package-tree.html   |    4 +-
 .../hadoop/hbase/regionserver/package-tree.html    |   18 +-
 .../hbase/regionserver/wal/package-tree.html       |    6 +-
 .../hadoop/hbase/security/access/package-tree.html |    6 +-
 .../apache/hadoop/hbase/security/package-tree.html |    2 +-
 .../apache/hadoop/hbase/thrift/package-tree.html   |    2 +-
 .../org/apache/hadoop/hbase/util/package-tree.html |   10 +-
 .../BalancerClusterState.DefaultRackManager.html   | 1653 ++++++++++----------
 .../BalancerClusterState.LocalityType.html         | 1653 ++++++++++----------
 .../master/balancer/BalancerClusterState.html      | 1653 ++++++++++----------
 .../balancer/RegionReplicaCandidateGenerator.html  |  154 +-
 .../RegionReplicaGroupingCostFunction.html         |  160 +-
 .../balancer/RegionReplicaHostCostFunction.html    |  106 +-
 .../RegionReplicaRackCandidateGenerator.html       |    2 +-
 .../balancer/RegionReplicaRackCostFunction.html    |    8 +-
 downloads.html                                     |    2 +-
 export_control.html                                |    2 +-
 index.html                                         |    2 +-
 issue-tracking.html                                |    2 +-
 mail-lists.html                                    |    2 +-
 metrics.html                                       |    2 +-
 old_news.html                                      |    2 +-
 plugin-management.html                             |    2 +-
 plugins.html                                       |    2 +-
 poweredbyhbase.html                                |    2 +-
 project-info.html                                  |    2 +-
 project-reports.html                               |    2 +-
 project-summary.html                               |    2 +-
 pseudo-distributed.html                            |    2 +-
 replication.html                                   |    2 +-
 resources.html                                     |    2 +-
 source-repository.html                             |    2 +-
 sponsors.html                                      |    2 +-
 supportingprojects.html                            |    2 +-
 team-list.html                                     |    2 +-
 .../hadoop/hbase/chaos/actions/package-tree.html   |    2 +-
 .../apache/hadoop/hbase/io/hfile/package-tree.html |    2 +-
 .../TestStochasticLoadBalancer.MockCluster.html    |   76 +-
 .../org/apache/hadoop/hbase/package-tree.html      |   14 +-
 .../hadoop/hbase/procedure/package-tree.html       |    8 +-
 .../hadoop/hbase/procedure2/package-tree.html      |    2 +-
 .../hadoop/hbase/regionserver/package-tree.html    |    8 +-
 .../org/apache/hadoop/hbase/test/package-tree.html |    6 +-
 .../org/apache/hadoop/hbase/wal/package-tree.html  |    2 +-
 ...rRegionReplicaWithRacks.ForTestRackManager.html |   10 +-
 ...ochasticLoadBalancerRegionReplicaWithRacks.html |   10 +-
 82 files changed, 3139 insertions(+), 3089 deletions(-)

diff --git a/acid-semantics.html b/acid-semantics.html
index 1f91550..da181c0 100644
--- a/acid-semantics.html
+++ b/acid-semantics.html
@@ -456,7 +456,7 @@
         <div class="row">
             <p>Copyright &copy;2007&#x2013;2021
 <a href="https://www.apache.org/">The Apache Software Foundation</a>.
-All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2021-09-22</li>
+All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2021-09-25</li>
 </p>
         </div>
         <p id="poweredBy" class="pull-right"><a href="http://maven.apache.org/" title="Built by Maven" class="poweredBy"><img class="builtBy" alt="Built by Maven" src="./images/logos/maven-feather.png" /></a>
diff --git a/apache_hbase_reference_guide.pdf b/apache_hbase_reference_guide.pdf
index a9c0844..0e809cc 100644
--- a/apache_hbase_reference_guide.pdf
+++ b/apache_hbase_reference_guide.pdf
@@ -5,8 +5,8 @@
 /Author (Apache HBase Team)
 /Creator (Asciidoctor PDF 1.5.3, based on Prawn 2.2.2)
 /Producer (Apache HBase Team)
-/ModDate (D:20210922200513+00'00')
-/CreationDate (D:20210922201505+00'00')
+/ModDate (D:20210925200527+00'00')
+/CreationDate (D:20210925201514+00'00')
 >>
 endobj
 2 0 obj
diff --git a/book.html b/book.html
index 2f0e601..acbeec5 100644
--- a/book.html
+++ b/book.html
@@ -46227,7 +46227,7 @@ org/apache/hadoop/hbase/security/access/AccessControlClient.revoke:(Lorg/apache/
 <div id="footer">
 <div id="footer-text">
 Version 3.0.0-alpha-2-SNAPSHOT<br>
-Last updated 2021-09-22 20:05:13 UTC
+Last updated 2021-09-25 20:05:27 UTC
 </div>
 </div>
 <link rel="stylesheet" href="./coderay-asciidoctor.css">
diff --git a/bulk-loads.html b/bulk-loads.html
index b309ac3..6a93f53 100644
--- a/bulk-loads.html
+++ b/bulk-loads.html
@@ -161,7 +161,7 @@
         <div class="row">
             <p>Copyright &copy;2007&#x2013;2021
 <a href="https://www.apache.org/">The Apache Software Foundation</a>.
-All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2021-09-22</li>
+All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2021-09-25</li>
 </p>
         </div>
         <p id="poweredBy" class="pull-right"><a href="http://maven.apache.org/" title="Built by Maven" class="poweredBy"><img class="builtBy" alt="Built by Maven" src="./images/logos/maven-feather.png" /></a>
diff --git a/checkstyle-aggregate.html b/checkstyle-aggregate.html
index 654c4ad..5d9446d 100644
--- a/checkstyle-aggregate.html
+++ b/checkstyle-aggregate.html
@@ -7298,7 +7298,7 @@
 <tr class="a">
 <td>annotation</td>
 <td><a class="externalLink" href="http://checkstyle.sourceforge.net/config_annotation.html#MissingDeprecated">MissingDeprecated</a></td>
-<td>6</td>
+<td>8</td>
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td></tr>
 <tr class="b">
 <td>blocks</td>
@@ -7397,7 +7397,7 @@
 <td><a class="externalLink" href="http://checkstyle.sourceforge.net/config_javadoc.html#JavadocTagContinuationIndentation">JavadocTagContinuationIndentation</a>
 <ul>
 <li>offset: <tt>&quot;2&quot;</tt></li></ul></td>
-<td>525</td>
+<td>523</td>
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td></tr>
 <tr class="b">
 <td></td>
@@ -35349,8 +35349,8 @@
 <th>Line</th></tr>
 <tr class="b">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
-<td>javadoc</td>
-<td>JavadocTagContinuationIndentation</td>
+<td>annotation</td>
+<td>MissingDeprecated</td>
 <td>Javadoc comment at column 14 has parse error. Details: mismatched input ':' expecting &lt;EOF&gt; while parsing JAVADOC</td>
 <td>46</td></tr></table></div>
 <div class="section">
@@ -40631,8 +40631,8 @@
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>sizes</td>
 <td>MethodLength</td>
-<td>Method length is 274 lines (max allowed is 150).</td>
-<td>130</td></tr></table></div>
+<td>Method length is 232 lines (max allowed is 150).</td>
+<td>134</td></tr></table></div>
 <div class="section">
 <h3 id="org.apache.hadoop.hbase.master.balancer.BalancerTestBase.java">org/apache/hadoop/hbase/master/balancer/BalancerTestBase.java</h3>
 <table border="0" class="table table-striped">
@@ -50220,8 +50220,8 @@
 <th>Line</th></tr>
 <tr class="b">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
-<td>javadoc</td>
-<td>JavadocTagContinuationIndentation</td>
+<td>annotation</td>
+<td>MissingDeprecated</td>
 <td>Javadoc comment at column 54 has parse error. Details: no viable alternative at input '(' while parsing JAVADOC_INLINE_TAG</td>
 <td>59</td></tr>
 <tr class="a">
@@ -73488,7 +73488,7 @@
         <div class="row">
             <p>Copyright &copy;2007&#x2013;2021
 <a href="https://www.apache.org/">The Apache Software Foundation</a>.
-All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2021-09-22</li>
+All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2021-09-25</li>
 </p>
         </div>
         <p id="poweredBy" class="pull-right"><a href="http://maven.apache.org/" title="Built by Maven" class="poweredBy"><img class="builtBy" alt="Built by Maven" src="./images/logos/maven-feather.png" /></a>
diff --git a/coc.html b/coc.html
index a709145..8d16cf0 100644
--- a/coc.html
+++ b/coc.html
@@ -230,7 +230,7 @@ email to <a class="externalLink" href="mailto:private@hbase.apache.org">the priv
         <div class="row">
             <p>Copyright &copy;2007&#x2013;2021
 <a href="https://www.apache.org/">The Apache Software Foundation</a>.
-All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2021-09-22</li>
+All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2021-09-25</li>
 </p>
         </div>
         <p id="poweredBy" class="pull-right"><a href="http://maven.apache.org/" title="Built by Maven" class="poweredBy"><img class="builtBy" alt="Built by Maven" src="./images/logos/maven-feather.png" /></a>
diff --git a/dependencies.html b/dependencies.html
index 6e2f2b8..0cd13bb 100644
--- a/dependencies.html
+++ b/dependencies.html
@@ -302,7 +302,7 @@
         <div class="row">
             <p>Copyright &copy;2007&#x2013;2021
 <a href="https://www.apache.org/">The Apache Software Foundation</a>.
-All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2021-09-22</li>
+All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2021-09-25</li>
 </p>
         </div>
         <p id="poweredBy" class="pull-right"><a href="http://maven.apache.org/" title="Built by Maven" class="poweredBy"><img class="builtBy" alt="Built by Maven" src="./images/logos/maven-feather.png" /></a>
diff --git a/dependency-convergence.html b/dependency-convergence.html
index 5a749e6..3b5508e 100644
--- a/dependency-convergence.html
+++ b/dependency-convergence.html
@@ -159,10 +159,10 @@
 <td>43</td></tr>
 <tr class="a">
 <th>Number of dependencies (NOD):</th>
-<td>261</td></tr>
+<td>262</td></tr>
 <tr class="b">
 <th>Number of unique artifacts (NOA):</th>
-<td>280</td></tr>
+<td>281</td></tr>
 <tr class="a">
 <th>Number of version-conflicting artifacts (NOC):</th>
 <td>17</td></tr>
@@ -866,7 +866,7 @@
         <div class="row">
             <p>Copyright &copy;2007&#x2013;2021
 <a href="https://www.apache.org/">The Apache Software Foundation</a>.
-All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2021-09-22</li>
+All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2021-09-25</li>
 </p>
         </div>
         <p id="poweredBy" class="pull-right"><a href="http://maven.apache.org/" title="Built by Maven" class="poweredBy"><img class="builtBy" alt="Built by Maven" src="./images/logos/maven-feather.png" /></a>
diff --git a/dependency-info.html b/dependency-info.html
index 0e36f5f..c604a01 100644
--- a/dependency-info.html
+++ b/dependency-info.html
@@ -183,7 +183,7 @@
         <div class="row">
             <p>Copyright &copy;2007&#x2013;2021
 <a href="https://www.apache.org/">The Apache Software Foundation</a>.
-All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2021-09-22</li>
+All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2021-09-25</li>
 </p>
         </div>
         <p id="poweredBy" class="pull-right"><a href="http://maven.apache.org/" title="Built by Maven" class="poweredBy"><img class="builtBy" alt="Built by Maven" src="./images/logos/maven-feather.png" /></a>
diff --git a/dependency-management.html b/dependency-management.html
index ab85d10..a23ce23 100644
--- a/dependency-management.html
+++ b/dependency-management.html
@@ -1190,7 +1190,7 @@
         <div class="row">
             <p>Copyright &copy;2007&#x2013;2021
 <a href="https://www.apache.org/">The Apache Software Foundation</a>.
-All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2021-09-22</li>
+All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2021-09-25</li>
 </p>
         </div>
         <p id="poweredBy" class="pull-right"><a href="http://maven.apache.org/" title="Built by Maven" class="poweredBy"><img class="builtBy" alt="Built by Maven" src="./images/logos/maven-feather.png" /></a>
diff --git a/devapidocs/index-all.html b/devapidocs/index-all.html
index 8424221..768ae15 100644
--- a/devapidocs/index-all.html
+++ b/devapidocs/index-all.html
@@ -11690,6 +11690,10 @@
 <dd>&nbsp;</dd>
 <dt><span class="memberNameLink"><a href="org/apache/hadoop/hbase/regionserver/RSRpcServices.html#checkLimitOfRows-int-int-boolean-org.apache.hadoop.hbase.regionserver.ScannerContext-org.apache.hadoop.hbase.shaded.protobuf.generated.ClientProtos.ScanResponse.Builder-">checkLimitOfRows(int, int, boolean, ScannerContext, ClientProtos.ScanResponse.Builder)</a></span> - Method in class org.apache.hadoop.hbase.regionserver.<a href="org/apache/hadoop/hbase/regionserver/RSRpcServices.html" titl [...]
 <dd>&nbsp;</dd>
+<dt><span class="memberNameLink"><a href="org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#checkLocationForPrimary-int-org.agrona.collections.Int2IntCounterMap:A-int-">checkLocationForPrimary(int, Int2IntCounterMap[], int)</a></span> - Method in class org.apache.hadoop.hbase.master.balancer.<a href="org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html" title="class in org.apache.hadoop.hbase.master.balancer">BalancerClusterState</a></dt>
+<dd>
+<div class="block">Common method for better solution check.</div>
+</dd>
 <dt><span class="memberNameLink"><a href="org/apache/hadoop/hbase/security/access/AccessChecker.html#checkLockPermissions-org.apache.hadoop.hbase.security.User-java.lang.String-org.apache.hadoop.hbase.TableName-org.apache.hadoop.hbase.client.RegionInfo:A-java.lang.String-">checkLockPermissions(User, String, TableName, RegionInfo[], String)</a></span> - Method in class org.apache.hadoop.hbase.security.access.<a href="org/apache/hadoop/hbase/security/access/AccessChecker.html" title="class [...]
 <dd>&nbsp;</dd>
 <dt><span class="memberNameLink"><a href="org/apache/hadoop/hbase/security/access/AccessController.html#checkLockPermissions-org.apache.hadoop.hbase.coprocessor.ObserverContext-java.lang.String-org.apache.hadoop.hbase.TableName-org.apache.hadoop.hbase.client.RegionInfo:A-java.lang.String-">checkLockPermissions(ObserverContext&lt;?&gt;, String, TableName, RegionInfo[], String)</a></span> - Method in class org.apache.hadoop.hbase.security.access.<a href="org/apache/hadoop/hbase/security/ac [...]
@@ -15060,6 +15064,14 @@
 <dd>&nbsp;</dd>
 <dt><span class="memberNameLink"><a href="org/apache/hadoop/hbase/PrivateCellUtil.FirstOnRowColByteBufferExtendedCell.html#colLength">colLength</a></span> - Variable in class org.apache.hadoop.hbase.<a href="org/apache/hadoop/hbase/PrivateCellUtil.FirstOnRowColByteBufferExtendedCell.html" title="class in org.apache.hadoop.hbase">PrivateCellUtil.FirstOnRowColByteBufferExtendedCell</a></dt>
 <dd>&nbsp;</dd>
+<dt><span class="memberNameLink"><a href="org/apache/hadoop/hbase/master/balancer/RegionReplicaHostCostFunction.html#colocatedReplicaCountsPerGroup">colocatedReplicaCountsPerGroup</a></span> - Variable in class org.apache.hadoop.hbase.master.balancer.<a href="org/apache/hadoop/hbase/master/balancer/RegionReplicaHostCostFunction.html" title="class in org.apache.hadoop.hbase.master.balancer">RegionReplicaHostCostFunction</a></dt>
+<dd>&nbsp;</dd>
+<dt><span class="memberNameLink"><a href="org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#colocatedReplicaCountsPerHost">colocatedReplicaCountsPerHost</a></span> - Variable in class org.apache.hadoop.hbase.master.balancer.<a href="org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html" title="class in org.apache.hadoop.hbase.master.balancer">BalancerClusterState</a></dt>
+<dd>&nbsp;</dd>
+<dt><span class="memberNameLink"><a href="org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#colocatedReplicaCountsPerRack">colocatedReplicaCountsPerRack</a></span> - Variable in class org.apache.hadoop.hbase.master.balancer.<a href="org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html" title="class in org.apache.hadoop.hbase.master.balancer">BalancerClusterState</a></dt>
+<dd>&nbsp;</dd>
+<dt><span class="memberNameLink"><a href="org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#colocatedReplicaCountsPerServer">colocatedReplicaCountsPerServer</a></span> - Variable in class org.apache.hadoop.hbase.master.balancer.<a href="org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html" title="class in org.apache.hadoop.hbase.master.balancer">BalancerClusterState</a></dt>
+<dd>&nbsp;</dd>
 <dt><span class="memberNameLink"><a href="org/apache/hadoop/hbase/PrivateCellUtil.FirstOnRowColByteBufferExtendedCell.html#colOffset">colOffset</a></span> - Variable in class org.apache.hadoop.hbase.<a href="org/apache/hadoop/hbase/PrivateCellUtil.FirstOnRowColByteBufferExtendedCell.html" title="class in org.apache.hadoop.hbase">PrivateCellUtil.FirstOnRowColByteBufferExtendedCell</a></dt>
 <dd>&nbsp;</dd>
 <dt><span class="memberNameLink"><a href="org/apache/hadoop/hbase/filter/ParseConstants.html#COLON">COLON</a></span> - Static variable in class org.apache.hadoop.hbase.filter.<a href="org/apache/hadoop/hbase/filter/ParseConstants.html" title="class in org.apache.hadoop.hbase.filter">ParseConstants</a></dt>
@@ -19892,7 +19904,7 @@
 <dd>&nbsp;</dd>
 <dt><span class="memberNameLink"><a href="org/apache/hadoop/hbase/coprocessor/example/ExampleRegionObserverWithMetrics.html#costlyOperationTimer">costlyOperationTimer</a></span> - Variable in class org.apache.hadoop.hbase.coprocessor.example.<a href="org/apache/hadoop/hbase/coprocessor/example/ExampleRegionObserverWithMetrics.html" title="class in org.apache.hadoop.hbase.coprocessor.example">ExampleRegionObserverWithMetrics</a></dt>
 <dd>&nbsp;</dd>
-<dt><span class="memberNameLink"><a href="org/apache/hadoop/hbase/master/balancer/RegionReplicaGroupingCostFunction.html#costPerGroup-int:A-">costPerGroup(int[])</a></span> - Method in class org.apache.hadoop.hbase.master.balancer.<a href="org/apache/hadoop/hbase/master/balancer/RegionReplicaGroupingCostFunction.html" title="class in org.apache.hadoop.hbase.master.balancer">RegionReplicaGroupingCostFunction</a></dt>
+<dt><span class="memberNameLink"><a href="org/apache/hadoop/hbase/master/balancer/RegionReplicaGroupingCostFunction.html#costPerGroup-org.agrona.collections.Int2IntCounterMap-">costPerGroup(Int2IntCounterMap)</a></span> - Method in class org.apache.hadoop.hbase.master.balancer.<a href="org/apache/hadoop/hbase/master/balancer/RegionReplicaGroupingCostFunction.html" title="class in org.apache.hadoop.hbase.master.balancer">RegionReplicaGroupingCostFunction</a></dt>
 <dd>
 <div class="block">For each primary region, it computes the total number of replicas in the array (numReplicas)
  and returns a sum of numReplicas-1 squared.</div>
@@ -89914,6 +89926,8 @@ service.</div>
 <dd>&nbsp;</dd>
 <dt><span class="memberNameLink"><a href="org/apache/hadoop/hbase/tool/CanaryTool.html#populateReadTableTimeoutsMap-java.lang.String-">populateReadTableTimeoutsMap(String)</a></span> - Method in class org.apache.hadoop.hbase.tool.<a href="org/apache/hadoop/hbase/tool/CanaryTool.html" title="class in org.apache.hadoop.hbase.tool">CanaryTool</a></dt>
 <dd>&nbsp;</dd>
+<dt><span class="memberNameLink"><a href="org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#populateRegionPerLocationFromServer-int:A:A-org.agrona.collections.Int2IntCounterMap:A-int:A:A-">populateRegionPerLocationFromServer(int[][], Int2IntCounterMap[], int[][])</a></span> - Method in class org.apache.hadoop.hbase.master.balancer.<a href="org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html" title="class in org.apache.hadoop.hbase.master.balancer">BalancerCl [...]
+<dd>&nbsp;</dd>
 <dt><span class="memberNameLink"><a href="org/apache/hadoop/hbase/regionserver/RegionScannerImpl.html#populateResult-java.util.List-org.apache.hadoop.hbase.regionserver.KeyValueHeap-org.apache.hadoop.hbase.regionserver.ScannerContext-org.apache.hadoop.hbase.Cell-">populateResult(List&lt;Cell&gt;, KeyValueHeap, ScannerContext, Cell)</a></span> - Method in class org.apache.hadoop.hbase.regionserver.<a href="org/apache/hadoop/hbase/regionserver/RegionScannerImpl.html" title="class in org.ap [...]
 <dd>
 <div class="block">Fetches records with currentRow into results list, until next row, batchLimit (if not -1) is
@@ -93289,14 +93303,6 @@ service.</div>
 </dd>
 <dt><span class="memberNameLink"><a href="org/apache/hadoop/hbase/regionserver/wal/WALCoprocessorHost.html#preWALWrite-org.apache.hadoop.hbase.client.RegionInfo-org.apache.hadoop.hbase.wal.WALKey-org.apache.hadoop.hbase.wal.WALEdit-">preWALWrite(RegionInfo, WALKey, WALEdit)</a></span> - Method in class org.apache.hadoop.hbase.regionserver.wal.<a href="org/apache/hadoop/hbase/regionserver/wal/WALCoprocessorHost.html" title="class in org.apache.hadoop.hbase.regionserver.wal">WALCoprocessor [...]
 <dd>&nbsp;</dd>
-<dt><span class="memberNameLink"><a href="org/apache/hadoop/hbase/master/balancer/RegionReplicaHostCostFunction.html#primariesOfRegionsPerGroup">primariesOfRegionsPerGroup</a></span> - Variable in class org.apache.hadoop.hbase.master.balancer.<a href="org/apache/hadoop/hbase/master/balancer/RegionReplicaHostCostFunction.html" title="class in org.apache.hadoop.hbase.master.balancer">RegionReplicaHostCostFunction</a></dt>
-<dd>&nbsp;</dd>
-<dt><span class="memberNameLink"><a href="org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#primariesOfRegionsPerHost">primariesOfRegionsPerHost</a></span> - Variable in class org.apache.hadoop.hbase.master.balancer.<a href="org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html" title="class in org.apache.hadoop.hbase.master.balancer">BalancerClusterState</a></dt>
-<dd>&nbsp;</dd>
-<dt><span class="memberNameLink"><a href="org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#primariesOfRegionsPerRack">primariesOfRegionsPerRack</a></span> - Variable in class org.apache.hadoop.hbase.master.balancer.<a href="org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html" title="class in org.apache.hadoop.hbase.master.balancer">BalancerClusterState</a></dt>
-<dd>&nbsp;</dd>
-<dt><span class="memberNameLink"><a href="org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#primariesOfRegionsPerServer">primariesOfRegionsPerServer</a></span> - Variable in class org.apache.hadoop.hbase.master.balancer.<a href="org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html" title="class in org.apache.hadoop.hbase.master.balancer">BalancerClusterState</a></dt>
-<dd>&nbsp;</dd>
 <dt><span class="memberNameLink"><a href="org/apache/hadoop/hbase/client/ConnectionConfiguration.html#PRIMARY_CALL_TIMEOUT_MICROSECOND">PRIMARY_CALL_TIMEOUT_MICROSECOND</a></span> - Static variable in class org.apache.hadoop.hbase.client.<a href="org/apache/hadoop/hbase/client/ConnectionConfiguration.html" title="class in org.apache.hadoop.hbase.client">ConnectionConfiguration</a></dt>
 <dd>&nbsp;</dd>
 <dt><span class="memberNameLink"><a href="org/apache/hadoop/hbase/client/ConnectionConfiguration.html#PRIMARY_CALL_TIMEOUT_MICROSECOND_DEFAULT">PRIMARY_CALL_TIMEOUT_MICROSECOND_DEFAULT</a></span> - Static variable in class org.apache.hadoop.hbase.client.<a href="org/apache/hadoop/hbase/client/ConnectionConfiguration.html" title="class in org.apache.hadoop.hbase.client">ConnectionConfiguration</a></dt>
@@ -108313,7 +108319,7 @@ service.</div>
 <dd>
 <div class="block">Selects a ZK client port.</div>
 </dd>
-<dt><span class="memberNameLink"><a href="org/apache/hadoop/hbase/master/balancer/RegionReplicaCandidateGenerator.html#selectCoHostedRegionPerGroup-int:A-int:A-int:A-">selectCoHostedRegionPerGroup(int[], int[], int[])</a></span> - Method in class org.apache.hadoop.hbase.master.balancer.<a href="org/apache/hadoop/hbase/master/balancer/RegionReplicaCandidateGenerator.html" title="class in org.apache.hadoop.hbase.master.balancer">RegionReplicaCandidateGenerator</a></dt>
+<dt><span class="memberNameLink"><a href="org/apache/hadoop/hbase/master/balancer/RegionReplicaCandidateGenerator.html#selectCoHostedRegionPerGroup-org.agrona.collections.Int2IntCounterMap-int:A-int:A-">selectCoHostedRegionPerGroup(Int2IntCounterMap, int[], int[])</a></span> - Method in class org.apache.hadoop.hbase.master.balancer.<a href="org/apache/hadoop/hbase/master/balancer/RegionReplicaCandidateGenerator.html" title="class in org.apache.hadoop.hbase.master.balancer">RegionReplicaC [...]
 <dd>
 <div class="block">Randomly select one regionIndex out of all region replicas co-hosted in the same group (a group
  is a server, host or rack)</div>
@@ -129336,6 +129342,10 @@ service.</div>
 </dd>
 <dt><span class="memberNameLink"><a href="org/apache/hadoop/hbase/regionserver/MetricsTableSourceImpl.html#updateFlushTime-long-">updateFlushTime(long)</a></span> - Method in class org.apache.hadoop.hbase.regionserver.<a href="org/apache/hadoop/hbase/regionserver/MetricsTableSourceImpl.html" title="class in org.apache.hadoop.hbase.regionserver">MetricsTableSourceImpl</a></dt>
 <dd>&nbsp;</dd>
+<dt><span class="memberNameLink"><a href="org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#updateForLocation-int:A-int:A:A-org.agrona.collections.Int2IntCounterMap:A-int-int-int-int-">updateForLocation(int[], int[][], Int2IntCounterMap[], int, int, int, int)</a></span> - Method in class org.apache.hadoop.hbase.master.balancer.<a href="org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html" title="class in org.apache.hadoop.hbase.master.balancer">BalancerCluste [...]
+<dd>
+<div class="block">Common method for per host and per Location region index updates when a region is moved.</div>
+</dd>
 <dt><span class="memberNameLink"><a href="org/apache/hadoop/hbase/io/MetricsIO.html#updateFsPreadTime-long-">updateFsPreadTime(long)</a></span> - Method in class org.apache.hadoop.hbase.io.<a href="org/apache/hadoop/hbase/io/MetricsIO.html" title="class in org.apache.hadoop.hbase.io">MetricsIO</a></dt>
 <dd>&nbsp;</dd>
 <dt><span class="memberNameLink"><a href="org/apache/hadoop/hbase/io/MetricsIOSource.html#updateFsPReadTime-long-">updateFsPReadTime(long)</a></span> - Method in interface org.apache.hadoop.hbase.io.<a href="org/apache/hadoop/hbase/io/MetricsIOSource.html" title="interface in org.apache.hadoop.hbase.io">MetricsIOSource</a></dt>
diff --git a/devapidocs/org/apache/hadoop/hbase/backup/package-tree.html b/devapidocs/org/apache/hadoop/hbase/backup/package-tree.html
index 097b483..233124d 100644
--- a/devapidocs/org/apache/hadoop/hbase/backup/package-tree.html
+++ b/devapidocs/org/apache/hadoop/hbase/backup/package-tree.html
@@ -166,10 +166,10 @@
 <ul>
 <li type="circle">java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Enum.html?is-external=true" title="class or interface in java.lang"><span class="typeNameLink">Enum</span></a>&lt;E&gt; (implements java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Comparable.html?is-external=true" title="class or interface in java.lang">Comparable</a>&lt;T&gt;, java.io.<a href="https://docs.oracle.com/javase/8/docs/api/java/io/Serializable.html?is-external=true [...]
 <ul>
-<li type="circle">org.apache.hadoop.hbase.backup.<a href="../../../../../org/apache/hadoop/hbase/backup/BackupInfo.BackupPhase.html" title="enum in org.apache.hadoop.hbase.backup"><span class="typeNameLink">BackupInfo.BackupPhase</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.backup.<a href="../../../../../org/apache/hadoop/hbase/backup/BackupType.html" title="enum in org.apache.hadoop.hbase.backup"><span class="typeNameLink">BackupType</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.backup.<a href="../../../../../org/apache/hadoop/hbase/backup/BackupInfo.BackupState.html" title="enum in org.apache.hadoop.hbase.backup"><span class="typeNameLink">BackupInfo.BackupState</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.backup.<a href="../../../../../org/apache/hadoop/hbase/backup/BackupRestoreConstants.BackupCommand.html" title="enum in org.apache.hadoop.hbase.backup"><span class="typeNameLink">BackupRestoreConstants.BackupCommand</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.backup.<a href="../../../../../org/apache/hadoop/hbase/backup/BackupType.html" title="enum in org.apache.hadoop.hbase.backup"><span class="typeNameLink">BackupType</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.backup.<a href="../../../../../org/apache/hadoop/hbase/backup/BackupInfo.BackupPhase.html" title="enum in org.apache.hadoop.hbase.backup"><span class="typeNameLink">BackupInfo.BackupPhase</span></a></li>
 </ul>
 </li>
 </ul>
diff --git a/devapidocs/org/apache/hadoop/hbase/client/package-tree.html b/devapidocs/org/apache/hadoop/hbase/client/package-tree.html
index 4d22607..9e353a8 100644
--- a/devapidocs/org/apache/hadoop/hbase/client/package-tree.html
+++ b/devapidocs/org/apache/hadoop/hbase/client/package-tree.html
@@ -466,25 +466,25 @@
 <ul>
 <li type="circle">java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Enum.html?is-external=true" title="class or interface in java.lang"><span class="typeNameLink">Enum</span></a>&lt;E&gt; (implements java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Comparable.html?is-external=true" title="class or interface in java.lang">Comparable</a>&lt;T&gt;, java.io.<a href="https://docs.oracle.com/javase/8/docs/api/java/io/Serializable.html?is-external=true [...]
 <ul>
-<li type="circle">org.apache.hadoop.hbase.client.<a href="../../../../../org/apache/hadoop/hbase/client/AbstractResponse.ResponseType.html" title="enum in org.apache.hadoop.hbase.client"><span class="typeNameLink">AbstractResponse.ResponseType</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.client.<a href="../../../../../org/apache/hadoop/hbase/client/Durability.html" title="enum in org.apache.hadoop.hbase.client"><span class="typeNameLink">Durability</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.client.<a href="../../../../../org/apache/hadoop/hbase/client/ServerType.html" title="enum in org.apache.hadoop.hbase.client"><span class="typeNameLink">ServerType</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.client.<a href="../../../../../org/apache/hadoop/hbase/client/Consistency.html" title="enum in org.apache.hadoop.hbase.client"><span class="typeNameLink">Consistency</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.client.<a href="../../../../../org/apache/hadoop/hbase/client/CompactionState.html" title="enum in org.apache.hadoop.hbase.client"><span class="typeNameLink">CompactionState</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.client.<a href="../../../../../org/apache/hadoop/hbase/client/LogQueryFilter.Type.html" title="enum in org.apache.hadoop.hbase.client"><span class="typeNameLink">LogQueryFilter.Type</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.client.<a href="../../../../../org/apache/hadoop/hbase/client/SnapshotType.html" title="enum in org.apache.hadoop.hbase.client"><span class="typeNameLink">SnapshotType</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.client.<a href="../../../../../org/apache/hadoop/hbase/client/MasterSwitchType.html" title="enum in org.apache.hadoop.hbase.client"><span class="typeNameLink">MasterSwitchType</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.client.<a href="../../../../../org/apache/hadoop/hbase/client/Durability.html" title="enum in org.apache.hadoop.hbase.client"><span class="typeNameLink">Durability</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.client.<a href="../../../../../org/apache/hadoop/hbase/client/RequestController.ReturnCode.html" title="enum in org.apache.hadoop.hbase.client"><span class="typeNameLink">RequestController.ReturnCode</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.client.<a href="../../../../../org/apache/hadoop/hbase/client/RegionLocateType.html" title="enum in org.apache.hadoop.hbase.client"><span class="typeNameLink">RegionLocateType</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.client.<a href="../../../../../org/apache/hadoop/hbase/client/AsyncScanSingleRegionRpcRetryingCaller.ScanControllerState.html" title="enum in org.apache.hadoop.hbase.client"><span class="typeNameLink">AsyncScanSingleRegionRpcRetryingCaller.ScanControllerState</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.client.<a href="../../../../../org/apache/hadoop/hbase/client/AsyncScanSingleRegionRpcRetryingCaller.ScanResumerState.html" title="enum in org.apache.hadoop.hbase.client"><span class="typeNameLink">AsyncScanSingleRegionRpcRetryingCaller.ScanResumerState</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.client.<a href="../../../../../org/apache/hadoop/hbase/client/LogQueryFilter.FilterByOperator.html" title="enum in org.apache.hadoop.hbase.client"><span class="typeNameLink">LogQueryFilter.FilterByOperator</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.client.<a href="../../../../../org/apache/hadoop/hbase/client/TableState.State.html" title="enum in org.apache.hadoop.hbase.client"><span class="typeNameLink">TableState.State</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.client.<a href="../../../../../org/apache/hadoop/hbase/client/MobCompactPartitionPolicy.html" title="enum in org.apache.hadoop.hbase.client"><span class="typeNameLink">MobCompactPartitionPolicy</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.client.<a href="../../../../../org/apache/hadoop/hbase/client/CompactType.html" title="enum in org.apache.hadoop.hbase.client"><span class="typeNameLink">CompactType</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.client.<a href="../../../../../org/apache/hadoop/hbase/client/Scan.ReadType.html" title="enum in org.apache.hadoop.hbase.client"><span class="typeNameLink">Scan.ReadType</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.client.<a href="../../../../../org/apache/hadoop/hbase/client/CompactType.html" title="enum in org.apache.hadoop.hbase.client"><span class="typeNameLink">CompactType</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.client.<a href="../../../../../org/apache/hadoop/hbase/client/AsyncScanSingleRegionRpcRetryingCaller.ScanControllerState.html" title="enum in org.apache.hadoop.hbase.client"><span class="typeNameLink">AsyncScanSingleRegionRpcRetryingCaller.ScanControllerState</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.client.<a href="../../../../../org/apache/hadoop/hbase/client/IsolationLevel.html" title="enum in org.apache.hadoop.hbase.client"><span class="typeNameLink">IsolationLevel</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.client.<a href="../../../../../org/apache/hadoop/hbase/client/AbstractResponse.ResponseType.html" title="enum in org.apache.hadoop.hbase.client"><span class="typeNameLink">AbstractResponse.ResponseType</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.client.<a href="../../../../../org/apache/hadoop/hbase/client/CatalogReplicaMode.html" title="enum in org.apache.hadoop.hbase.client"><span class="typeNameLink">CatalogReplicaMode</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.client.<a href="../../../../../org/apache/hadoop/hbase/client/LogQueryFilter.Type.html" title="enum in org.apache.hadoop.hbase.client"><span class="typeNameLink">LogQueryFilter.Type</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.client.<a href="../../../../../org/apache/hadoop/hbase/client/AsyncScanSingleRegionRpcRetryingCaller.ScanResumerState.html" title="enum in org.apache.hadoop.hbase.client"><span class="typeNameLink">AsyncScanSingleRegionRpcRetryingCaller.ScanResumerState</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.client.<a href="../../../../../org/apache/hadoop/hbase/client/ServerType.html" title="enum in org.apache.hadoop.hbase.client"><span class="typeNameLink">ServerType</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.client.<a href="../../../../../org/apache/hadoop/hbase/client/RegionLocateType.html" title="enum in org.apache.hadoop.hbase.client"><span class="typeNameLink">RegionLocateType</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.client.<a href="../../../../../org/apache/hadoop/hbase/client/MobCompactPartitionPolicy.html" title="enum in org.apache.hadoop.hbase.client"><span class="typeNameLink">MobCompactPartitionPolicy</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.client.<a href="../../../../../org/apache/hadoop/hbase/client/Consistency.html" title="enum in org.apache.hadoop.hbase.client"><span class="typeNameLink">Consistency</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.client.<a href="../../../../../org/apache/hadoop/hbase/client/MasterSwitchType.html" title="enum in org.apache.hadoop.hbase.client"><span class="typeNameLink">MasterSwitchType</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.client.<a href="../../../../../org/apache/hadoop/hbase/client/TableState.State.html" title="enum in org.apache.hadoop.hbase.client"><span class="typeNameLink">TableState.State</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.client.<a href="../../../../../org/apache/hadoop/hbase/client/SnapshotType.html" title="enum in org.apache.hadoop.hbase.client"><span class="typeNameLink">SnapshotType</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.client.<a href="../../../../../org/apache/hadoop/hbase/client/LogQueryFilter.FilterByOperator.html" title="enum in org.apache.hadoop.hbase.client"><span class="typeNameLink">LogQueryFilter.FilterByOperator</span></a></li>
 </ul>
 </li>
 </ul>
diff --git a/devapidocs/org/apache/hadoop/hbase/coprocessor/package-tree.html b/devapidocs/org/apache/hadoop/hbase/coprocessor/package-tree.html
index ce4e541..b424234 100644
--- a/devapidocs/org/apache/hadoop/hbase/coprocessor/package-tree.html
+++ b/devapidocs/org/apache/hadoop/hbase/coprocessor/package-tree.html
@@ -176,8 +176,8 @@
 <ul>
 <li type="circle">java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Enum.html?is-external=true" title="class or interface in java.lang"><span class="typeNameLink">Enum</span></a>&lt;E&gt; (implements java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Comparable.html?is-external=true" title="class or interface in java.lang">Comparable</a>&lt;T&gt;, java.io.<a href="https://docs.oracle.com/javase/8/docs/api/java/io/Serializable.html?is-external=true [...]
 <ul>
-<li type="circle">org.apache.hadoop.hbase.coprocessor.<a href="../../../../../org/apache/hadoop/hbase/coprocessor/RegionObserver.MutationType.html" title="enum in org.apache.hadoop.hbase.coprocessor"><span class="typeNameLink">RegionObserver.MutationType</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.coprocessor.<a href="../../../../../org/apache/hadoop/hbase/coprocessor/MetaTableMetrics.MetaTableOps.html" title="enum in org.apache.hadoop.hbase.coprocessor"><span class="typeNameLink">MetaTableMetrics.MetaTableOps</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.coprocessor.<a href="../../../../../org/apache/hadoop/hbase/coprocessor/RegionObserver.MutationType.html" title="enum in org.apache.hadoop.hbase.coprocessor"><span class="typeNameLink">RegionObserver.MutationType</span></a></li>
 </ul>
 </li>
 </ul>
diff --git a/devapidocs/org/apache/hadoop/hbase/filter/package-tree.html b/devapidocs/org/apache/hadoop/hbase/filter/package-tree.html
index 720a266..e0df853 100644
--- a/devapidocs/org/apache/hadoop/hbase/filter/package-tree.html
+++ b/devapidocs/org/apache/hadoop/hbase/filter/package-tree.html
@@ -190,13 +190,13 @@
 <ul>
 <li type="circle">java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Enum.html?is-external=true" title="class or interface in java.lang"><span class="typeNameLink">Enum</span></a>&lt;E&gt; (implements java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Comparable.html?is-external=true" title="class or interface in java.lang">Comparable</a>&lt;T&gt;, java.io.<a href="https://docs.oracle.com/javase/8/docs/api/java/io/Serializable.html?is-external=true [...]
 <ul>
-<li type="circle">org.apache.hadoop.hbase.filter.<a href="../../../../../org/apache/hadoop/hbase/filter/FuzzyRowFilter.Order.html" title="enum in org.apache.hadoop.hbase.filter"><span class="typeNameLink">FuzzyRowFilter.Order</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.filter.<a href="../../../../../org/apache/hadoop/hbase/filter/Filter.ReturnCode.html" title="enum in org.apache.hadoop.hbase.filter"><span class="typeNameLink">Filter.ReturnCode</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.filter.<a href="../../../../../org/apache/hadoop/hbase/filter/BitComparator.BitwiseOp.html" title="enum in org.apache.hadoop.hbase.filter"><span class="typeNameLink">BitComparator.BitwiseOp</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.filter.<a href="../../../../../org/apache/hadoop/hbase/filter/FilterWrapper.FilterRowRetCode.html" title="enum in org.apache.hadoop.hbase.filter"><span class="typeNameLink">FilterWrapper.FilterRowRetCode</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.filter.<a href="../../../../../org/apache/hadoop/hbase/filter/FilterList.Operator.html" title="enum in org.apache.hadoop.hbase.filter"><span class="typeNameLink">FilterList.Operator</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.filter.<a href="../../../../../org/apache/hadoop/hbase/filter/RegexStringComparator.EngineType.html" title="enum in org.apache.hadoop.hbase.filter"><span class="typeNameLink">RegexStringComparator.EngineType</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.filter.<a href="../../../../../org/apache/hadoop/hbase/filter/FilterList.Operator.html" title="enum in org.apache.hadoop.hbase.filter"><span class="typeNameLink">FilterList.Operator</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.filter.<a href="../../../../../org/apache/hadoop/hbase/filter/FuzzyRowFilter.SatisfiesCode.html" title="enum in org.apache.hadoop.hbase.filter"><span class="typeNameLink">FuzzyRowFilter.SatisfiesCode</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.filter.<a href="../../../../../org/apache/hadoop/hbase/filter/Filter.ReturnCode.html" title="enum in org.apache.hadoop.hbase.filter"><span class="typeNameLink">Filter.ReturnCode</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.filter.<a href="../../../../../org/apache/hadoop/hbase/filter/FuzzyRowFilter.Order.html" title="enum in org.apache.hadoop.hbase.filter"><span class="typeNameLink">FuzzyRowFilter.Order</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.filter.<a href="../../../../../org/apache/hadoop/hbase/filter/FilterWrapper.FilterRowRetCode.html" title="enum in org.apache.hadoop.hbase.filter"><span class="typeNameLink">FilterWrapper.FilterRowRetCode</span></a></li>
 </ul>
 </li>
 </ul>
diff --git a/devapidocs/org/apache/hadoop/hbase/hbtop/field/package-tree.html b/devapidocs/org/apache/hadoop/hbase/hbtop/field/package-tree.html
index 96318e7..4245577 100644
--- a/devapidocs/org/apache/hadoop/hbase/hbtop/field/package-tree.html
+++ b/devapidocs/org/apache/hadoop/hbase/hbtop/field/package-tree.html
@@ -92,8 +92,8 @@
 <ul>
 <li type="circle">java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Enum.html?is-external=true" title="class or interface in java.lang"><span class="typeNameLink">Enum</span></a>&lt;E&gt; (implements java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Comparable.html?is-external=true" title="class or interface in java.lang">Comparable</a>&lt;T&gt;, java.io.<a href="https://docs.oracle.com/javase/8/docs/api/java/io/Serializable.html?is-external=true [...]
 <ul>
-<li type="circle">org.apache.hadoop.hbase.hbtop.field.<a href="../../../../../../org/apache/hadoop/hbase/hbtop/field/FieldValueType.html" title="enum in org.apache.hadoop.hbase.hbtop.field"><span class="typeNameLink">FieldValueType</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.hbtop.field.<a href="../../../../../../org/apache/hadoop/hbase/hbtop/field/Field.html" title="enum in org.apache.hadoop.hbase.hbtop.field"><span class="typeNameLink">Field</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.hbtop.field.<a href="../../../../../../org/apache/hadoop/hbase/hbtop/field/FieldValueType.html" title="enum in org.apache.hadoop.hbase.hbtop.field"><span class="typeNameLink">FieldValueType</span></a></li>
 </ul>
 </li>
 </ul>
diff --git a/devapidocs/org/apache/hadoop/hbase/hbtop/terminal/package-tree.html b/devapidocs/org/apache/hadoop/hbase/hbtop/terminal/package-tree.html
index 5a984ee..85ba9c8 100644
--- a/devapidocs/org/apache/hadoop/hbase/hbtop/terminal/package-tree.html
+++ b/devapidocs/org/apache/hadoop/hbase/hbtop/terminal/package-tree.html
@@ -107,8 +107,8 @@
 <ul>
 <li type="circle">java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Enum.html?is-external=true" title="class or interface in java.lang"><span class="typeNameLink">Enum</span></a>&lt;E&gt; (implements java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Comparable.html?is-external=true" title="class or interface in java.lang">Comparable</a>&lt;T&gt;, java.io.<a href="https://docs.oracle.com/javase/8/docs/api/java/io/Serializable.html?is-external=true [...]
 <ul>
-<li type="circle">org.apache.hadoop.hbase.hbtop.terminal.<a href="../../../../../../org/apache/hadoop/hbase/hbtop/terminal/KeyPress.Type.html" title="enum in org.apache.hadoop.hbase.hbtop.terminal"><span class="typeNameLink">KeyPress.Type</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.hbtop.terminal.<a href="../../../../../../org/apache/hadoop/hbase/hbtop/terminal/Color.html" title="enum in org.apache.hadoop.hbase.hbtop.terminal"><span class="typeNameLink">Color</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.hbtop.terminal.<a href="../../../../../../org/apache/hadoop/hbase/hbtop/terminal/KeyPress.Type.html" title="enum in org.apache.hadoop.hbase.hbtop.terminal"><span class="typeNameLink">KeyPress.Type</span></a></li>
 </ul>
 </li>
 </ul>
diff --git a/devapidocs/org/apache/hadoop/hbase/http/package-tree.html b/devapidocs/org/apache/hadoop/hbase/http/package-tree.html
index 3f1a9b2..f22d03f 100644
--- a/devapidocs/org/apache/hadoop/hbase/http/package-tree.html
+++ b/devapidocs/org/apache/hadoop/hbase/http/package-tree.html
@@ -141,8 +141,8 @@
 <li type="circle">java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Enum.html?is-external=true" title="class or interface in java.lang"><span class="typeNameLink">Enum</span></a>&lt;E&gt; (implements java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Comparable.html?is-external=true" title="class or interface in java.lang">Comparable</a>&lt;T&gt;, java.io.<a href="https://docs.oracle.com/javase/8/docs/api/java/io/Serializable.html?is-external=true [...]
 <ul>
 <li type="circle">org.apache.hadoop.hbase.http.<a href="../../../../../org/apache/hadoop/hbase/http/ProfileServlet.Event.html" title="enum in org.apache.hadoop.hbase.http"><span class="typeNameLink">ProfileServlet.Event</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.http.<a href="../../../../../org/apache/hadoop/hbase/http/ProfileServlet.Output.html" title="enum in org.apache.hadoop.hbase.http"><span class="typeNameLink">ProfileServlet.Output</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.http.<a href="../../../../../org/apache/hadoop/hbase/http/HttpConfig.Policy.html" title="enum in org.apache.hadoop.hbase.http"><span class="typeNameLink">HttpConfig.Policy</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.http.<a href="../../../../../org/apache/hadoop/hbase/http/ProfileServlet.Output.html" title="enum in org.apache.hadoop.hbase.http"><span class="typeNameLink">ProfileServlet.Output</span></a></li>
 </ul>
 </li>
 </ul>
diff --git a/devapidocs/org/apache/hadoop/hbase/io/hfile/package-tree.html b/devapidocs/org/apache/hadoop/hbase/io/hfile/package-tree.html
index e3b93a0..d1ec882 100644
--- a/devapidocs/org/apache/hadoop/hbase/io/hfile/package-tree.html
+++ b/devapidocs/org/apache/hadoop/hbase/io/hfile/package-tree.html
@@ -309,11 +309,11 @@
 <ul>
 <li type="circle">java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Enum.html?is-external=true" title="class or interface in java.lang"><span class="typeNameLink">Enum</span></a>&lt;E&gt; (implements java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Comparable.html?is-external=true" title="class or interface in java.lang">Comparable</a>&lt;T&gt;, java.io.<a href="https://docs.oracle.com/javase/8/docs/api/java/io/Serializable.html?is-external=true [...]
 <ul>
-<li type="circle">org.apache.hadoop.hbase.io.hfile.<a href="../../../../../../org/apache/hadoop/hbase/io/hfile/BlockPriority.html" title="enum in org.apache.hadoop.hbase.io.hfile"><span class="typeNameLink">BlockPriority</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.io.hfile.<a href="../../../../../../org/apache/hadoop/hbase/io/hfile/BlockType.html" title="enum in org.apache.hadoop.hbase.io.hfile"><span class="typeNameLink">BlockType</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.io.hfile.<a href="../../../../../../org/apache/hadoop/hbase/io/hfile/BlockPriority.html" title="enum in org.apache.hadoop.hbase.io.hfile"><span class="typeNameLink">BlockPriority</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.io.hfile.<a href="../../../../../../org/apache/hadoop/hbase/io/hfile/HFileBlock.Writer.State.html" title="enum in org.apache.hadoop.hbase.io.hfile"><span class="typeNameLink">HFileBlock.Writer.State</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.io.hfile.<a href="../../../../../../org/apache/hadoop/hbase/io/hfile/ReaderContext.ReaderType.html" title="enum in org.apache.hadoop.hbase.io.hfile"><span class="typeNameLink">ReaderContext.ReaderType</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.io.hfile.<a href="../../../../../../org/apache/hadoop/hbase/io/hfile/BlockCacheFactory.ExternalBlockCaches.html" title="enum in org.apache.hadoop.hbase.io.hfile"><span class="typeNameLink">BlockCacheFactory.ExternalBlockCaches</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.io.hfile.<a href="../../../../../../org/apache/hadoop/hbase/io/hfile/ReaderContext.ReaderType.html" title="enum in org.apache.hadoop.hbase.io.hfile"><span class="typeNameLink">ReaderContext.ReaderType</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.io.hfile.<a href="../../../../../../org/apache/hadoop/hbase/io/hfile/BlockType.BlockCategory.html" title="enum in org.apache.hadoop.hbase.io.hfile"><span class="typeNameLink">BlockType.BlockCategory</span></a></li>
 </ul>
 </li>
diff --git a/devapidocs/org/apache/hadoop/hbase/ipc/package-tree.html b/devapidocs/org/apache/hadoop/hbase/ipc/package-tree.html
index 3ce9ea6..a6b11eb 100644
--- a/devapidocs/org/apache/hadoop/hbase/ipc/package-tree.html
+++ b/devapidocs/org/apache/hadoop/hbase/ipc/package-tree.html
@@ -363,9 +363,9 @@
 <ul>
 <li type="circle">java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Enum.html?is-external=true" title="class or interface in java.lang"><span class="typeNameLink">Enum</span></a>&lt;E&gt; (implements java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Comparable.html?is-external=true" title="class or interface in java.lang">Comparable</a>&lt;T&gt;, java.io.<a href="https://docs.oracle.com/javase/8/docs/api/java/io/Serializable.html?is-external=true [...]
 <ul>
-<li type="circle">org.apache.hadoop.hbase.ipc.<a href="../../../../../org/apache/hadoop/hbase/ipc/CallEvent.Type.html" title="enum in org.apache.hadoop.hbase.ipc"><span class="typeNameLink">CallEvent.Type</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.ipc.<a href="../../../../../org/apache/hadoop/hbase/ipc/BufferCallBeforeInitHandler.BufferCallAction.html" title="enum in org.apache.hadoop.hbase.ipc"><span class="typeNameLink">BufferCallBeforeInitHandler.BufferCallAction</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.ipc.<a href="../../../../../org/apache/hadoop/hbase/ipc/MetricsHBaseServerSourceFactoryImpl.SourceStorage.html" title="enum in org.apache.hadoop.hbase.ipc"><span class="typeNameLink">MetricsHBaseServerSourceFactoryImpl.SourceStorage</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.ipc.<a href="../../../../../org/apache/hadoop/hbase/ipc/BufferCallBeforeInitHandler.BufferCallAction.html" title="enum in org.apache.hadoop.hbase.ipc"><span class="typeNameLink">BufferCallBeforeInitHandler.BufferCallAction</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.ipc.<a href="../../../../../org/apache/hadoop/hbase/ipc/CallEvent.Type.html" title="enum in org.apache.hadoop.hbase.ipc"><span class="typeNameLink">CallEvent.Type</span></a></li>
 </ul>
 </li>
 </ul>
diff --git a/devapidocs/org/apache/hadoop/hbase/mapreduce/package-tree.html b/devapidocs/org/apache/hadoop/hbase/mapreduce/package-tree.html
index f1e8e71..84cec8e 100644
--- a/devapidocs/org/apache/hadoop/hbase/mapreduce/package-tree.html
+++ b/devapidocs/org/apache/hadoop/hbase/mapreduce/package-tree.html
@@ -301,9 +301,9 @@
 <li type="circle">java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Enum.html?is-external=true" title="class or interface in java.lang"><span class="typeNameLink">Enum</span></a>&lt;E&gt; (implements java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Comparable.html?is-external=true" title="class or interface in java.lang">Comparable</a>&lt;T&gt;, java.io.<a href="https://docs.oracle.com/javase/8/docs/api/java/io/Serializable.html?is-external=true [...]
 <ul>
 <li type="circle">org.apache.hadoop.hbase.mapreduce.<a href="../../../../../org/apache/hadoop/hbase/mapreduce/CellCounter.CellCounterMapper.Counters.html" title="enum in org.apache.hadoop.hbase.mapreduce"><span class="typeNameLink">CellCounter.CellCounterMapper.Counters</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.mapreduce.<a href="../../../../../org/apache/hadoop/hbase/mapreduce/WALPlayer.Counter.html" title="enum in org.apache.hadoop.hbase.mapreduce"><span class="typeNameLink">WALPlayer.Counter</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.mapreduce.<a href="../../../../../org/apache/hadoop/hbase/mapreduce/SyncTable.SyncMapper.Counter.html" title="enum in org.apache.hadoop.hbase.mapreduce"><span class="typeNameLink">SyncTable.SyncMapper.Counter</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.mapreduce.<a href="../../../../../org/apache/hadoop/hbase/mapreduce/TableSplit.Version.html" title="enum in org.apache.hadoop.hbase.mapreduce"><span class="typeNameLink">TableSplit.Version</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.mapreduce.<a href="../../../../../org/apache/hadoop/hbase/mapreduce/WALPlayer.Counter.html" title="enum in org.apache.hadoop.hbase.mapreduce"><span class="typeNameLink">WALPlayer.Counter</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.mapreduce.<a href="../../../../../org/apache/hadoop/hbase/mapreduce/RowCounter.RowCounterMapper.Counters.html" title="enum in org.apache.hadoop.hbase.mapreduce"><span class="typeNameLink">RowCounter.RowCounterMapper.Counters</span></a></li>
 </ul>
 </li>
diff --git a/devapidocs/org/apache/hadoop/hbase/master/assignment/package-tree.html b/devapidocs/org/apache/hadoop/hbase/master/assignment/package-tree.html
index ba98778..8bede26 100644
--- a/devapidocs/org/apache/hadoop/hbase/master/assignment/package-tree.html
+++ b/devapidocs/org/apache/hadoop/hbase/master/assignment/package-tree.html
@@ -151,8 +151,8 @@
 <ul>
 <li type="circle">java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Enum.html?is-external=true" title="class or interface in java.lang"><span class="typeNameLink">Enum</span></a>&lt;E&gt; (implements java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Comparable.html?is-external=true" title="class or interface in java.lang">Comparable</a>&lt;T&gt;, java.io.<a href="https://docs.oracle.com/javase/8/docs/api/java/io/Serializable.html?is-external=true [...]
 <ul>
-<li type="circle">org.apache.hadoop.hbase.master.assignment.<a href="../../../../../../org/apache/hadoop/hbase/master/assignment/ServerState.html" title="enum in org.apache.hadoop.hbase.master.assignment"><span class="typeNameLink">ServerState</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.master.assignment.<a href="../../../../../../org/apache/hadoop/hbase/master/assignment/TransitRegionStateProcedure.TransitionType.html" title="enum in org.apache.hadoop.hbase.master.assignment"><span class="typeNameLink">TransitRegionStateProcedure.TransitionType</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.master.assignment.<a href="../../../../../../org/apache/hadoop/hbase/master/assignment/ServerState.html" title="enum in org.apache.hadoop.hbase.master.assignment"><span class="typeNameLink">ServerState</span></a></li>
 </ul>
 </li>
 </ul>
diff --git a/devapidocs/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.DefaultRackManager.html b/devapidocs/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.DefaultRackManager.html
index 0a4a6fc..991a579 100644
--- a/devapidocs/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.DefaultRackManager.html
+++ b/devapidocs/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.DefaultRackManager.html
@@ -118,7 +118,7 @@ var activeTableTab = "activeTableTab";
 </dl>
 <hr>
 <br>
-<pre>static class <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#line.117">BalancerClusterState.DefaultRackManager</a>
+<pre>static class <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#line.121">BalancerClusterState.DefaultRackManager</a>
 extends <a href="../../../../../../org/apache/hadoop/hbase/master/RackManager.html" title="class in org.apache.hadoop.hbase.master">RackManager</a></pre>
 </li>
 </ul>
@@ -212,7 +212,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/RackManager.ht
 <ul class="blockListLast">
 <li class="blockList">
 <h4>DefaultRackManager</h4>
-<pre><a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.DefaultRackManager.html#line.117">DefaultRackManager</a>()</pre>
+<pre><a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.DefaultRackManager.html#line.121">DefaultRackManager</a>()</pre>
 </li>
 </ul>
 </li>
@@ -229,7 +229,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/RackManager.ht
 <ul class="blockListLast">
 <li class="blockList">
 <h4>getRack</h4>
-<pre>public&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a>&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.DefaultRackManager.html#line.119">getRack</a>(<a href="../../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>&nbsp;server)</pre>
+<pre>public&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a>&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.DefaultRackManager.html#line.123">getRack</a>(<a href="../../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>&nbsp;server)</pre>
 <div class="block"><span class="descfrmTypeLabel">Description copied from class:&nbsp;<code><a href="../../../../../../org/apache/hadoop/hbase/master/RackManager.html#getRack-org.apache.hadoop.hbase.ServerName-">RackManager</a></code></span></div>
 <div class="block">Get the name of the rack containing a server, according to the DNS to
  switch mapping.</div>
diff --git a/devapidocs/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.LocalityType.html b/devapidocs/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.LocalityType.html
index ff694d9..25435cc 100644
--- a/devapidocs/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.LocalityType.html
+++ b/devapidocs/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.LocalityType.html
@@ -122,7 +122,7 @@ var activeTableTab = "activeTableTab";
 </dl>
 <hr>
 <br>
-<pre>static enum <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#line.563">BalancerClusterState.LocalityType</a>
+<pre>static enum <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#line.553">BalancerClusterState.LocalityType</a>
 extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Enum.html?is-external=true" title="class or interface in java.lang">Enum</a>&lt;<a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BalancerClusterState.LocalityType.html" title="enum in org.apache.hadoop.hbase.master.balancer">BalancerClusterState.LocalityType</a>&gt;</pre>
 </li>
 </ul>
@@ -210,7 +210,7 @@ the order they are declared.</div>
 <ul class="blockList">
 <li class="blockList">
 <h4>SERVER</h4>
-<pre>public static final&nbsp;<a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BalancerClusterState.LocalityType.html" title="enum in org.apache.hadoop.hbase.master.balancer">BalancerClusterState.LocalityType</a> <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.LocalityType.html#line.564">SERVER</a></pre>
+<pre>public static final&nbsp;<a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BalancerClusterState.LocalityType.html" title="enum in org.apache.hadoop.hbase.master.balancer">BalancerClusterState.LocalityType</a> <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.LocalityType.html#line.554">SERVER</a></pre>
 </li>
 </ul>
 <a name="RACK">
@@ -219,7 +219,7 @@ the order they are declared.</div>
 <ul class="blockListLast">
 <li class="blockList">
 <h4>RACK</h4>
-<pre>public static final&nbsp;<a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BalancerClusterState.LocalityType.html" title="enum in org.apache.hadoop.hbase.master.balancer">BalancerClusterState.LocalityType</a> <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.LocalityType.html#line.564">RACK</a></pre>
+<pre>public static final&nbsp;<a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BalancerClusterState.LocalityType.html" title="enum in org.apache.hadoop.hbase.master.balancer">BalancerClusterState.LocalityType</a> <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.LocalityType.html#line.554">RACK</a></pre>
 </li>
 </ul>
 </li>
diff --git a/devapidocs/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html b/devapidocs/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html
index c0de644..399fb64 100644
--- a/devapidocs/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html
+++ b/devapidocs/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html
@@ -18,7 +18,7 @@
     catch(err) {
     }
 //-->
-var methods = {"i0":10,"i1":10,"i2":10,"i3":10,"i4":10,"i5":10,"i6":10,"i7":10,"i8":10,"i9":10,"i10":10,"i11":10,"i12":10,"i13":10,"i14":10,"i15":10,"i16":10,"i17":10,"i18":10,"i19":10,"i20":10,"i21":10,"i22":10,"i23":10,"i24":10,"i25":10};
+var methods = {"i0":10,"i1":10,"i2":10,"i3":10,"i4":10,"i5":10,"i6":10,"i7":10,"i8":10,"i9":10,"i10":10,"i11":10,"i12":10,"i13":10,"i14":10,"i15":10,"i16":10,"i17":10,"i18":10,"i19":10,"i20":10,"i21":10,"i22":10,"i23":10,"i24":10,"i25":10,"i26":10,"i27":10,"i28":10};
 var tabs = {65535:["t0","All Methods"],2:["t2","Instance Methods"],8:["t4","Concrete Methods"]};
 var altColor = "altColor";
 var rowColor = "rowColor";
@@ -110,7 +110,7 @@ var activeTableTab = "activeTableTab";
 <hr>
 <br>
 <pre>@InterfaceAudience.Private
-class <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#line.49">BalancerClusterState</a>
+class <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#line.51">BalancerClusterState</a>
 extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">Object</a></pre>
 <div class="block">An efficient array based implementation similar to ClusterState for keeping the status of the
  cluster in terms of region assignment and distribution. LoadBalancers, such as
@@ -165,93 +165,93 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#clusterState">clusterState</a></span></code>&nbsp;</td>
 </tr>
 <tr class="rowColor">
+<td class="colFirst"><code>(package private) org.agrona.collections.Int2IntCounterMap[]</code></td>
+<td class="colLast"><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#colocatedReplicaCountsPerHost">colocatedReplicaCountsPerHost</a></span></code>&nbsp;</td>
+</tr>
+<tr class="altColor">
+<td class="colFirst"><code>(package private) org.agrona.collections.Int2IntCounterMap[]</code></td>
+<td class="colLast"><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#colocatedReplicaCountsPerRack">colocatedReplicaCountsPerRack</a></span></code>&nbsp;</td>
+</tr>
+<tr class="rowColor">
+<td class="colFirst"><code>(package private) org.agrona.collections.Int2IntCounterMap[]</code></td>
+<td class="colLast"><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#colocatedReplicaCountsPerServer">colocatedReplicaCountsPerServer</a></span></code>&nbsp;</td>
+</tr>
+<tr class="altColor">
 <td class="colFirst"><code>(package private) boolean</code></td>
 <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#hasRegionReplicas">hasRegionReplicas</a></span></code>&nbsp;</td>
 </tr>
-<tr class="altColor">
+<tr class="rowColor">
 <td class="colFirst"><code>(package private) <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a>[]</code></td>
 <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#hosts">hosts</a></span></code>&nbsp;</td>
 </tr>
-<tr class="rowColor">
+<tr class="altColor">
 <td class="colFirst"><code>(package private) <a href="https://docs.oracle.com/javase/8/docs/api/java/util/Map.html?is-external=true" title="class or interface in java.util">Map</a>&lt;<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a>,<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Integer.html?is-external=true" title="class or interface in java.lang">Integer</a>&gt;</code></td>
 <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#hostsToIndex">hostsToIndex</a></span></code>&nbsp;</td>
 </tr>
-<tr class="altColor">
+<tr class="rowColor">
 <td class="colFirst"><code>(package private) int[]</code></td>
 <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#initialRegionIndexToServerIndex">initialRegionIndexToServerIndex</a></span></code>&nbsp;</td>
 </tr>
-<tr class="rowColor">
+<tr class="altColor">
 <td class="colFirst"><code>(package private) float[]</code></td>
 <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#localityPerServer">localityPerServer</a></span></code>&nbsp;</td>
 </tr>
-<tr class="altColor">
+<tr class="rowColor">
 <td class="colFirst"><code>private static org.slf4j.Logger</code></td>
 <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#LOG">LOG</a></span></code>&nbsp;</td>
 </tr>
-<tr class="rowColor">
+<tr class="altColor">
 <td class="colFirst"><code>(package private) double[]</code></td>
 <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#maxRegionSkewByTable">maxRegionSkewByTable</a></span></code>&nbsp;</td>
 </tr>
-<tr class="altColor">
+<tr class="rowColor">
 <td class="colFirst"><code>(package private) double[]</code></td>
 <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#meanRegionsPerTable">meanRegionsPerTable</a></span></code>&nbsp;</td>
 </tr>
-<tr class="rowColor">
+<tr class="altColor">
 <td class="colFirst"><code>(package private) double[]</code></td>
 <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#minRegionSkewByTable">minRegionSkewByTable</a></span></code>&nbsp;</td>
 </tr>
-<tr class="altColor">
+<tr class="rowColor">
 <td class="colFirst"><code>(package private) boolean</code></td>
 <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#multiServersPerHost">multiServersPerHost</a></span></code>&nbsp;</td>
 </tr>
-<tr class="rowColor">
+<tr class="altColor">
 <td class="colFirst"><code>(package private) int</code></td>
 <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#numHosts">numHosts</a></span></code>&nbsp;</td>
 </tr>
-<tr class="altColor">
+<tr class="rowColor">
 <td class="colFirst"><code>(package private) int</code></td>
 <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#numMovedRegions">numMovedRegions</a></span></code>&nbsp;</td>
 </tr>
-<tr class="rowColor">
+<tr class="altColor">
 <td class="colFirst"><code>(package private) int</code></td>
 <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#numRacks">numRacks</a></span></code>&nbsp;</td>
 </tr>
-<tr class="altColor">
+<tr class="rowColor">
 <td class="colFirst"><code>(package private) int</code></td>
 <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#numRegions">numRegions</a></span></code>&nbsp;</td>
 </tr>
-<tr class="rowColor">
+<tr class="altColor">
 <td class="colFirst"><code>private <a href="https://docs.oracle.com/javase/8/docs/api/java/util/Comparator.html?is-external=true" title="class or interface in java.util">Comparator</a>&lt;<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Integer.html?is-external=true" title="class or interface in java.lang">Integer</a>&gt;</code></td>
 <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#numRegionsComparator">numRegionsComparator</a></span></code>&nbsp;</td>
 </tr>
-<tr class="altColor">
+<tr class="rowColor">
 <td class="colFirst"><code>(package private) int[][]</code></td>
 <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#numRegionsPerServerPerTable">numRegionsPerServerPerTable</a></span></code>&nbsp;</td>
 </tr>
-<tr class="rowColor">
+<tr class="altColor">
 <td class="colFirst"><code>(package private) int[]</code></td>
 <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#numRegionsPerTable">numRegionsPerTable</a></span></code>&nbsp;</td>
 </tr>
-<tr class="altColor">
+<tr class="rowColor">
 <td class="colFirst"><code>(package private) int</code></td>
 <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#numServers">numServers</a></span></code>&nbsp;</td>
 </tr>
-<tr class="rowColor">
+<tr class="altColor">
 <td class="colFirst"><code>(package private) int</code></td>
 <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#numTables">numTables</a></span></code>&nbsp;</td>
 </tr>
-<tr class="altColor">
-<td class="colFirst"><code>(package private) int[][]</code></td>
-<td class="colLast"><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#primariesOfRegionsPerHost">primariesOfRegionsPerHost</a></span></code>&nbsp;</td>
-</tr>
-<tr class="rowColor">
-<td class="colFirst"><code>(package private) int[][]</code></td>
-<td class="colLast"><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#primariesOfRegionsPerRack">primariesOfRegionsPerRack</a></span></code>&nbsp;</td>
-</tr>
-<tr class="altColor">
-<td class="colFirst"><code>(package private) int[][]</code></td>
-<td class="colLast"><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#primariesOfRegionsPerServer">primariesOfRegionsPerServer</a></span></code>&nbsp;</td>
-</tr>
 <tr class="rowColor">
 <td class="colFirst"><code>private float[][]</code></td>
 <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#rackLocalities">rackLocalities</a></span></code>&nbsp;</td>
@@ -417,6 +417,14 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
                int&nbsp;regionIndex)</code>&nbsp;</td>
 </tr>
 <tr id="i2" class="altColor">
+<td class="colFirst"><code>private int</code></td>
+<td class="colLast"><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#checkLocationForPrimary-int-org.agrona.collections.Int2IntCounterMap:A-int-">checkLocationForPrimary</a></span>(int&nbsp;location,
+                       org.agrona.collections.Int2IntCounterMap[]&nbsp;colocatedReplicaCountsPerLocation,
+                       int&nbsp;primary)</code>
+<div class="block">Common method for better solution check.</div>
+</td>
+</tr>
+<tr id="i3" class="rowColor">
 <td class="colFirst"><code>private void</code></td>
 <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#computeCachedLocalities--">computeCachedLocalities</a></span>()</code>
 <div class="block">Computes and caches the locality for each region/rack combinations, as well as storing a
@@ -424,34 +432,34 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
  locality for region</div>
 </td>
 </tr>
-<tr id="i3" class="rowColor">
+<tr id="i4" class="altColor">
 <td class="colFirst"><code>(package private) boolean</code></td>
 <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#contains-int:A-int-">contains</a></span>(int[]&nbsp;arr,
         int&nbsp;val)</code>&nbsp;</td>
 </tr>
-<tr id="i4" class="altColor">
+<tr id="i5" class="rowColor">
 <td class="colFirst"><code>void</code></td>
 <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#doAction-org.apache.hadoop.hbase.master.balancer.BalanceAction-">doAction</a></span>(<a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BalanceAction.html" title="class in org.apache.hadoop.hbase.master.balancer">BalanceAction</a>&nbsp;action)</code>&nbsp;</td>
 </tr>
-<tr id="i5" class="rowColor">
+<tr id="i6" class="altColor">
 <td class="colFirst"><code>(package private) void</code></td>
 <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#doAssignRegion-org.apache.hadoop.hbase.client.RegionInfo-org.apache.hadoop.hbase.ServerName-">doAssignRegion</a></span>(<a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;regionInfo,
               <a href="../../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>&nbsp;serverName)</code>&nbsp;</td>
 </tr>
-<tr id="i6" class="altColor">
+<tr id="i7" class="rowColor">
 <td class="colFirst"><code>(package private) float</code></td>
 <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#getLocalityOfRegion-int-int-">getLocalityOfRegion</a></span>(int&nbsp;region,
                    int&nbsp;server)</code>&nbsp;</td>
 </tr>
-<tr id="i7" class="rowColor">
+<tr id="i8" class="altColor">
 <td class="colFirst"><code>(package private) int</code></td>
 <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#getLowestLocalityRegionOnServer-int-">getLowestLocalityRegionOnServer</a></span>(int&nbsp;serverIndex)</code>&nbsp;</td>
 </tr>
-<tr id="i8" class="altColor">
+<tr id="i9" class="rowColor">
 <td class="colFirst"><code>(package private) int</code></td>
 <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#getNumRegions-int-">getNumRegions</a></span>(int&nbsp;server)</code>&nbsp;</td>
 </tr>
-<tr id="i9" class="rowColor">
+<tr id="i10" class="altColor">
 <td class="colFirst"><code>float</code></td>
 <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#getOrComputeLocality-int-int-org.apache.hadoop.hbase.master.balancer.BalancerClusterState.LocalityType-">getOrComputeLocality</a></span>(int&nbsp;region,
                     int&nbsp;entity,
@@ -459,21 +467,21 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <div class="block">Looks up locality from cache of localities.</div>
 </td>
 </tr>
-<tr id="i10" class="altColor">
+<tr id="i11" class="rowColor">
 <td class="colFirst"><code>float[][]</code></td>
 <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#getOrComputeRackLocalities--">getOrComputeRackLocalities</a></span>()</code>
 <div class="block">Retrieves and lazily initializes a field storing the locality of every region/server
  combination</div>
 </td>
 </tr>
-<tr id="i11" class="rowColor">
+<tr id="i12" class="altColor">
 <td class="colFirst"><code>int[]</code></td>
 <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#getOrComputeRegionsToMostLocalEntities-org.apache.hadoop.hbase.master.balancer.BalancerClusterState.LocalityType-">getOrComputeRegionsToMostLocalEntities</a></span>(<a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BalancerClusterState.LocalityType.html" title="enum in org.apache.hadoop.hbase.master.balancer">BalancerClusterS [...]
 <div class="block">Lazily initializes and retrieves a mapping of region -> server for which region has the highest
  the locality</div>
 </td>
 </tr>
-<tr id="i12" class="altColor">
+<tr id="i13" class="rowColor">
 <td class="colFirst"><code>double</code></td>
 <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#getOrComputeWeightedLocality-int-int-org.apache.hadoop.hbase.master.balancer.BalancerClusterState.LocalityType-">getOrComputeWeightedLocality</a></span>(int&nbsp;region,
                             int&nbsp;server,
@@ -481,31 +489,37 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <div class="block">Returns locality weighted by region size in MB.</div>
 </td>
 </tr>
-<tr id="i13" class="rowColor">
+<tr id="i14" class="altColor">
 <td class="colFirst"><code>int</code></td>
 <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#getRackForRegion-int-">getRackForRegion</a></span>(int&nbsp;region)</code>
 <div class="block">Maps region index to rack index</div>
 </td>
 </tr>
-<tr id="i14" class="altColor">
+<tr id="i15" class="rowColor">
 <td class="colFirst"><code>int</code></td>
 <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#getRegionSizeMB-int-">getRegionSizeMB</a></span>(int&nbsp;region)</code>
 <div class="block">Returns the size in MB from the most recent RegionLoad for region</div>
 </td>
 </tr>
-<tr id="i15" class="rowColor">
+<tr id="i16" class="altColor">
 <td class="colFirst"><code>private double</code></td>
 <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#getSkewChangeFor-int-int-int-">getSkewChangeFor</a></span>(int&nbsp;serverIndex,
                 int&nbsp;tableIndex,
                 int&nbsp;regionCountChange)</code>&nbsp;</td>
 </tr>
-<tr id="i16" class="altColor">
+<tr id="i17" class="rowColor">
+<td class="colFirst"><code>private void</code></td>
+<td class="colLast"><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#populateRegionPerLocationFromServer-int:A:A-org.agrona.collections.Int2IntCounterMap:A-int:A:A-">populateRegionPerLocationFromServer</a></span>(int[][]&nbsp;regionsPerLocation,
+                                   org.agrona.collections.Int2IntCounterMap[]&nbsp;colocatedReplicaCountsPerLocation,
+                                   int[][]&nbsp;serversPerLocation)</code>&nbsp;</td>
+</tr>
+<tr id="i18" class="altColor">
 <td class="colFirst"><code>(package private) void</code></td>
 <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#regionMoved-int-int-int-">regionMoved</a></span>(int&nbsp;region,
            int&nbsp;oldServer,
            int&nbsp;newServer)</code>&nbsp;</td>
 </tr>
-<tr id="i17" class="rowColor">
+<tr id="i19" class="rowColor">
 <td class="colFirst"><code>private void</code></td>
 <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#registerRegion-org.apache.hadoop.hbase.client.RegionInfo-int-int-java.util.Map-org.apache.hadoop.hbase.master.balancer.RegionHDFSBlockLocationFinder-">registerRegion</a></span>(<a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;region,
               int&nbsp;regionIndex,
@@ -515,40 +529,52 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <div class="block">Helper for Cluster constructor to handle a region</div>
 </td>
 </tr>
-<tr id="i18" class="altColor">
+<tr id="i20" class="altColor">
 <td class="colFirst"><code>(package private) int[]</code></td>
 <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#removeRegion-int:A-int-">removeRegion</a></span>(int[]&nbsp;regions,
             int&nbsp;regionIndex)</code>&nbsp;</td>
 </tr>
-<tr id="i19" class="rowColor">
+<tr id="i21" class="rowColor">
 <td class="colFirst"><code>(package private) int[]</code></td>
 <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#replaceRegion-int:A-int-int-">replaceRegion</a></span>(int[]&nbsp;regions,
              int&nbsp;regionIndex,
              int&nbsp;newRegionIndex)</code>&nbsp;</td>
 </tr>
-<tr id="i20" class="altColor">
+<tr id="i22" class="altColor">
 <td class="colFirst"><code>boolean</code></td>
 <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#serverHasTooFewRegions-int-">serverHasTooFewRegions</a></span>(int&nbsp;server)</code>
 <div class="block">Returns true iff a given server has less regions than the balanced amount</div>
 </td>
 </tr>
-<tr id="i21" class="rowColor">
+<tr id="i23" class="rowColor">
 <td class="colFirst"><code>(package private) void</code></td>
 <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#setNumMovedRegions-int-">setNumMovedRegions</a></span>(int&nbsp;numMovedRegions)</code>&nbsp;</td>
 </tr>
-<tr id="i22" class="altColor">
+<tr id="i24" class="altColor">
 <td class="colFirst"><code>(package private) void</code></td>
 <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#setNumRegions-int-">setNumRegions</a></span>(int&nbsp;numRegions)</code>&nbsp;</td>
 </tr>
-<tr id="i23" class="rowColor">
+<tr id="i25" class="rowColor">
 <td class="colFirst"><code>(package private) void</code></td>
 <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#sortServersByRegionCount--">sortServersByRegionCount</a></span>()</code>&nbsp;</td>
 </tr>
-<tr id="i24" class="altColor">
+<tr id="i26" class="altColor">
 <td class="colFirst"><code><a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a></code></td>
 <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#toString--">toString</a></span>()</code>&nbsp;</td>
 </tr>
-<tr id="i25" class="rowColor">
+<tr id="i27" class="rowColor">
+<td class="colFirst"><code>private void</code></td>
+<td class="colLast"><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#updateForLocation-int:A-int:A:A-org.agrona.collections.Int2IntCounterMap:A-int-int-int-int-">updateForLocation</a></span>(int[]&nbsp;serverIndexToLocation,
+                 int[][]&nbsp;regionsPerLocation,
+                 org.agrona.collections.Int2IntCounterMap[]&nbsp;colocatedReplicaCountsPerLocation,
+                 int&nbsp;oldServer,
+                 int&nbsp;newServer,
+                 int&nbsp;primary,
+                 int&nbsp;region)</code>
+<div class="block">Common method for per host and per Location region index updates when a region is moved.</div>
+</td>
+</tr>
+<tr id="i28" class="altColor">
 <td class="colFirst"><code>(package private) boolean</code></td>
 <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#wouldLowerAvailability-org.apache.hadoop.hbase.client.RegionInfo-org.apache.hadoop.hbase.ServerName-">wouldLowerAvailability</a></span>(<a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;regionInfo,
                       <a href="../../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>&nbsp;serverName)</code>
@@ -584,7 +610,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>LOG</h4>
-<pre>private static final&nbsp;org.slf4j.Logger <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#line.51">LOG</a></pre>
+<pre>private static final&nbsp;org.slf4j.Logger <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#line.53">LOG</a></pre>
 </li>
 </ul>
 <a name="servers">
@@ -593,7 +619,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>servers</h4>
-<pre><a href="../../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>[] <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#line.53">servers</a></pre>
+<pre><a href="../../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>[] <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#line.55">servers</a></pre>
 </li>
 </ul>
 <a name="hosts">
@@ -602,7 +628,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>hosts</h4>
-<pre><a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a>[] <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#line.55">hosts</a></pre>
+<pre><a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a>[] <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#line.57">hosts</a></pre>
 </li>
 </ul>
 <a name="racks">
@@ -611,7 +637,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>racks</h4>
-<pre><a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a>[] <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#line.56">racks</a></pre>
+<pre><a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a>[] <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#line.58">racks</a></pre>
 </li>
 </ul>
 <a name="multiServersPerHost">
@@ -620,7 +646,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>multiServersPerHost</h4>
-<pre>boolean <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#line.57">multiServersPerHost</a></pre>
+<pre>boolean <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#line.59">multiServersPerHost</a></pre>
 </li>
 </ul>
 <a name="tables">
@@ -629,7 +655,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>tables</h4>
-<pre><a href="https://docs.oracle.com/javase/8/docs/api/java/util/ArrayList.html?is-external=true" title="class or interface in java.util">ArrayList</a>&lt;<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a>&gt; <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#line.59">tables</a></pre>
+<pre><a href="https://docs.oracle.com/javase/8/docs/api/java/util/ArrayList.html?is-external=true" title="class or interface in java.util">ArrayList</a>&lt;<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a>&gt; <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#line.61">tables</a></pre>
 </li>
 </ul>
 <a name="regions">
@@ -638,7 +664,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>regions</h4>
-<pre><a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>[] <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#line.60">regions</a></pre>
+<pre><a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>[] <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#line.62">regions</a></pre>
 </li>
 </ul>
 <a name="regionLoads">
@@ -647,7 +673,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>regionLoads</h4>
-<pre><a href="https://docs.oracle.com/javase/8/docs/api/java/util/Deque.html?is-external=true" title="class or interface in java.util">Deque</a>&lt;<a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BalancerRegionLoad.html" title="class in org.apache.hadoop.hbase.master.balancer">BalancerRegionLoad</a>&gt;[] <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#line.61">regionLoads</a></pre>
+<pre><a href="https://docs.oracle.com/javase/8/docs/api/java/util/Deque.html?is-external=true" title="class or interface in java.util">Deque</a>&lt;<a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BalancerRegionLoad.html" title="class in org.apache.hadoop.hbase.master.balancer">BalancerRegionLoad</a>&gt;[] <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#line.63">regionLoads</a></pre>
 </li>
 </ul>
 <a name="regionFinder">
@@ -656,7 +682,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>regionFinder</h4>
-<pre>private&nbsp;<a href="../../../../../../org/apache/hadoop/hbase/master/balancer/RegionHDFSBlockLocationFinder.html" title="class in org.apache.hadoop.hbase.master.balancer">RegionHDFSBlockLocationFinder</a> <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#line.62">regionFinder</a></pre>
+<pre>private&nbsp;<a href="../../../../../../org/apache/hadoop/hbase/master/balancer/RegionHDFSBlockLocationFinder.html" title="class in org.apache.hadoop.hbase.master.balancer">RegionHDFSBlockLocationFinder</a> <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#line.64">regionFinder</a></pre>
 </li>
 </ul>
 <a name="regionLocations">
@@ -665,7 +691,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>regionLocations</h4>
-<pre>int[][] <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#line.64">regionLocations</a></pre>
+<pre>int[][] <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#line.66">regionLocations</a></pre>
 </li>
 </ul>
 <a name="serverIndexToHostIndex">
@@ -674,7 +700,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>serverIndexToHostIndex</h4>
-<pre>int[] <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#line.66">serverIndexToHostIndex</a></pre>
+<pre>int[] <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#line.68">serverIndexToHostIndex</a></pre>
 </li>
 </ul>
 <a name="serverIndexToRackIndex">
@@ -683,7 +709,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>serverIndexToRackIndex</h4>
-<pre>int[] <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#line.67">serverIndexToRackIndex</a></pre>
+<pre>int[] <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#line.69">serverIndexToRackIndex</a></pre>
 </li>
 </ul>
 <a name="regionsPerServer">
@@ -692,7 +718,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>regionsPerServer</h4>
-<pre>int[][] <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#line.69">regionsPerServer</a></pre>
+<pre>int[][] <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#line.71">regionsPerServer</a></pre>
 </li>
 </ul>
 <a name="serverIndexToRegionsOffset">
@@ -701,7 +727,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>serverIndexToRegionsOffset</h4>
-<pre>int[] <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#line.70">serverIndexToRegionsOffset</a></pre>
+<pre>int[] <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#line.72">serverIndexToRegionsOffset</a></pre>
 </li>
 </ul>
 <a name="regionsPerHost">
@@ -710,7 +736,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>regionsPerHost</h4>
-<pre>int[][] <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#line.71">regionsPerHost</a></pre>
+<pre>int[][] <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#line.73">regionsPerHost</a></pre>
 </li>
 </ul>
 <a name="regionsPerRack">
@@ -719,34 +745,34 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>regionsPerRack</h4>
-<pre>int[][] <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#line.72">regionsPerRack</a></pre>
+<pre>int[][] <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#line.74">regionsPerRack</a></pre>
 </li>
 </ul>
-<a name="primariesOfRegionsPerServer">
+<a name="colocatedReplicaCountsPerServer">
 <!--   -->
 </a>
 <ul class="blockList">
 <li class="blockList">
-<h4>primariesOfRegionsPerServer</h4>
-<pre>int[][] <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#line.73">primariesOfRegionsPerServer</a></pre>
+<h4>colocatedReplicaCountsPerServer</h4>
+<pre>org.agrona.collections.Int2IntCounterMap[] <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#line.75">colocatedReplicaCountsPerServer</a></pre>
 </li>
 </ul>
-<a name="primariesOfRegionsPerHost">
+<a name="colocatedReplicaCountsPerHost">
 <!--   -->
 </a>
 <ul class="blockList">
 <li class="blockList">
-<h4>primariesOfRegionsPerHost</h4>
-<pre>int[][] <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#line.75">primariesOfRegionsPerHost</a></pre>
+<h4>colocatedReplicaCountsPerHost</h4>
+<pre>org.agrona.collections.Int2IntCounterMap[] <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#line.77">colocatedReplicaCountsPerHost</a></pre>
 </li>
 </ul>
-<a name="primariesOfRegionsPerRack">
+<a name="colocatedReplicaCountsPerRack">
 <!--   -->
 </a>
 <ul class="blockList">
 <li class="blockList">
-<h4>primariesOfRegionsPerRack</h4>
-<pre>int[][] <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#line.76">primariesOfRegionsPerRack</a></pre>
+<h4>colocatedReplicaCountsPerRack</h4>
+<pre>org.agrona.collections.Int2IntCounterMap[] <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#line.79">colocatedReplicaCountsPerRack</a></pre>
 </li>
 </ul>
 <a name="serversPerHost">
@@ -755,7 +781,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>serversPerHost</h4>
-<pre>int[][] <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#line.78">serversPerHost</a></pre>
+<pre>int[][] <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#line.82">serversPerHost</a></pre>
 </li>
 </ul>
 <a name="serversPerRack">
@@ -764,7 +790,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>serversPerRack</h4>
-<pre>int[][] <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#line.79">serversPerRack</a></pre>
+<pre>int[][] <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#line.83">serversPerRack</a></pre>
 </li>
 </ul>
 <a name="regionIndexToServerIndex">
@@ -773,7 +799,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>regionIndexToServerIndex</h4>
-<pre>int[] <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#line.80">regionIndexToServerIndex</a></pre>
+<pre>int[] <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#line.84">regionIndexToServerIndex</a></pre>
 </li>
 </ul>
 <a name="initialRegionIndexToServerIndex">
@@ -782,7 +808,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>initialRegionIndexToServerIndex</h4>
-<pre>int[] <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#line.81">initialRegionIndexToServerIndex</a></pre>
+<pre>int[] <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#line.85">initialRegionIndexToServerIndex</a></pre>
 </li>
 </ul>
 <a name="regionIndexToTableIndex">
@@ -791,7 +817,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>regionIndexToTableIndex</h4>
-<pre>int[] <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#line.82">regionIndexToTableIndex</a></pre>
+<pre>int[] <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#line.86">regionIndexToTableIndex</a></pre>
 </li>
 </ul>
 <a name="numRegionsPerServerPerTable">
@@ -800,7 +826,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>numRegionsPerServerPerTable</h4>
-<pre>int[][] <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#line.83">numRegionsPerServerPerTable</a></pre>
+<pre>int[][] <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#line.87">numRegionsPerServerPerTable</a></pre>
 </li>
 </ul>
 <a name="numRegionsPerTable">
@@ -809,7 +835,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>numRegionsPerTable</h4>
-<pre>int[] <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#line.84">numRegionsPerTable</a></pre>
+<pre>int[] <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#line.88">numRegionsPerTable</a></pre>
 </li>
 </ul>
 <a name="meanRegionsPerTable">
@@ -818,7 +844,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>meanRegionsPerTable</h4>
-<pre>double[] <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#line.85">meanRegionsPerTable</a></pre>
+<pre>double[] <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#line.89">meanRegionsPerTable</a></pre>
 </li>
 </ul>
 <a name="regionSkewByTable">
@@ -827,7 +853,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>regionSkewByTable</h4>
-<pre>double[] <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#line.86">regionSkewByTable</a></pre>
+<pre>double[] <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#line.90">regionSkewByTable</a></pre>
 </li>
 </ul>
 <a name="minRegionSkewByTable">
@@ -836,7 +862,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>minRegionSkewByTable</h4>
-<pre>double[] <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#line.87">minRegionSkewByTable</a></pre>
+<pre>double[] <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#line.91">minRegionSkewByTable</a></pre>
 </li>
 </ul>
 <a name="maxRegionSkewByTable">
@@ -845,7 +871,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>maxRegionSkewByTable</h4>
-<pre>double[] <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#line.88">maxRegionSkewByTable</a></pre>
+<pre>double[] <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#line.92">maxRegionSkewByTable</a></pre>
 </li>
 </ul>
 <a name="regionIndexToPrimaryIndex">
@@ -854,7 +880,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>regionIndexToPrimaryIndex</h4>
-<pre>int[] <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#line.89">regionIndexToPrimaryIndex</a></pre>
+<pre>int[] <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#line.93">regionIndexToPrimaryIndex</a></pre>
 </li>
 </ul>
 <a name="hasRegionReplicas">
@@ -863,7 +889,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>hasRegionReplicas</h4>
-<pre>boolean <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#line.90">hasRegionReplicas</a></pre>
+<pre>boolean <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#line.94">hasRegionReplicas</a></pre>
 </li>
 </ul>
 <a name="serverIndicesSortedByRegionCount">
@@ -872,7 +898,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>serverIndicesSortedByRegionCount</h4>
-<pre><a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Integer.html?is-external=true" title="class or interface in java.lang">Integer</a>[] <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#line.92">serverIndicesSortedByRegionCount</a></pre>
+<pre><a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Integer.html?is-external=true" title="class or interface in java.lang">Integer</a>[] <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#line.96">serverIndicesSortedByRegionCount</a></pre>
 </li>
 </ul>
 <a name="serverIndicesSortedByLocality">
@@ -881,7 +907,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>serverIndicesSortedByLocality</h4>
-<pre><a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Integer.html?is-external=true" title="class or interface in java.lang">Integer</a>[] <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#line.93">serverIndicesSortedByLocality</a></pre>
+<pre><a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Integer.html?is-external=true" title="class or interface in java.lang">Integer</a>[] <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#line.97">serverIndicesSortedByLocality</a></pre>
 </li>
 </ul>
 <a name="serversToIndex">
@@ -890,7 +916,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>serversToIndex</h4>
-<pre><a href="https://docs.oracle.com/javase/8/docs/api/java/util/Map.html?is-external=true" title="class or interface in java.util">Map</a>&lt;<a href="../../../../../../org/apache/hadoop/hbase/net/Address.html" title="class in org.apache.hadoop.hbase.net">Address</a>,<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Integer.html?is-external=true" title="class or interface in java.lang">Integer</a>&gt; <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balance [...]
+<pre><a href="https://docs.oracle.com/javase/8/docs/api/java/util/Map.html?is-external=true" title="class or interface in java.util">Map</a>&lt;<a href="../../../../../../org/apache/hadoop/hbase/net/Address.html" title="class in org.apache.hadoop.hbase.net">Address</a>,<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Integer.html?is-external=true" title="class or interface in java.lang">Integer</a>&gt; <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balance [...]
 </li>
 </ul>
 <a name="hostsToIndex">
@@ -899,7 +925,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>hostsToIndex</h4>
-<pre><a href="https://docs.oracle.com/javase/8/docs/api/java/util/Map.html?is-external=true" title="class or interface in java.util">Map</a>&lt;<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a>,<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Integer.html?is-external=true" title="class or interface in java.lang">Integer</a>&gt; <a href="../../../../../../src-html/org/apache/hadoop/hbas [...]
+<pre><a href="https://docs.oracle.com/javase/8/docs/api/java/util/Map.html?is-external=true" title="class or interface in java.util">Map</a>&lt;<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a>,<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Integer.html?is-external=true" title="class or interface in java.lang">Integer</a>&gt; <a href="../../../../../../src-html/org/apache/hadoop/hbas [...]
 </li>
 </ul>
 <a name="racksToIndex">
@@ -908,7 +934,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>racksToIndex</h4>
-<pre><a href="https://docs.oracle.com/javase/8/docs/api/java/util/Map.html?is-external=true" title="class or interface in java.util">Map</a>&lt;<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a>,<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Integer.html?is-external=true" title="class or interface in java.lang">Integer</a>&gt; <a href="../../../../../../src-html/org/apache/hadoop/hbas [...]
+<pre><a href="https://docs.oracle.com/javase/8/docs/api/java/util/Map.html?is-external=true" title="class or interface in java.util">Map</a>&lt;<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a>,<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Integer.html?is-external=true" title="class or interface in java.lang">Integer</a>&gt; <a href="../../../../../../src-html/org/apache/hadoop/hbas [...]
 </li>
 </ul>
 <a name="tablesToIndex">
@@ -917,7 +943,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>tablesToIndex</h4>
-<pre><a href="https://docs.oracle.com/javase/8/docs/api/java/util/Map.html?is-external=true" title="class or interface in java.util">Map</a>&lt;<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a>,<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Integer.html?is-external=true" title="class or interface in java.lang">Integer</a>&gt; <a href="../../../../../../src-html/org/apache/hadoop/hbas [...]
+<pre><a href="https://docs.oracle.com/javase/8/docs/api/java/util/Map.html?is-external=true" title="class or interface in java.util">Map</a>&lt;<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a>,<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Integer.html?is-external=true" title="class or interface in java.lang">Integer</a>&gt; <a href="../../../../../../src-html/org/apache/hadoop/hbas [...]
 </li>
 </ul>
 <a name="regionsToIndex">
@@ -926,7 +952,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>regionsToIndex</h4>
-<pre><a href="https://docs.oracle.com/javase/8/docs/api/java/util/Map.html?is-external=true" title="class or interface in java.util">Map</a>&lt;<a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>,<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Integer.html?is-external=true" title="class or interface in java.lang">Integer</a>&gt; <a href="../../../../../../src-html/org/apache/hadoop/hbas [...]
+<pre><a href="https://docs.oracle.com/javase/8/docs/api/java/util/Map.html?is-external=true" title="class or interface in java.util">Map</a>&lt;<a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>,<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Integer.html?is-external=true" title="class or interface in java.lang">Integer</a>&gt; <a href="../../../../../../src-html/org/apache/hadoop/hbas [...]
 </li>
 </ul>
 <a name="localityPerServer">
@@ -935,7 +961,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>localityPerServer</h4>
-<pre>float[] <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#line.100">localityPerServer</a></pre>
+<pre>float[] <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#line.104">localityPerServer</a></pre>
 </li>
 </ul>
 <a name="numServers">
@@ -944,7 +970,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>numServers</h4>
-<pre>int <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#line.102">numServers</a></pre>
+<pre>int <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#line.106">numServers</a></pre>
 </li>
 </ul>
 <a name="numHosts">
@@ -953,7 +979,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>numHosts</h4>
-<pre>int <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#line.103">numHosts</a></pre>
+<pre>int <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#line.107">numHosts</a></pre>
 </li>
 </ul>
 <a name="numRacks">
@@ -962,7 +988,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>numRacks</h4>
-<pre>int <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#line.104">numRacks</a></pre>
+<pre>int <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#line.108">numRacks</a></pre>
 </li>
 </ul>
 <a name="numTables">
@@ -971,7 +997,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>numTables</h4>
-<pre>int <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#line.105">numTables</a></pre>
+<pre>int <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#line.109">numTables</a></pre>
 </li>
 </ul>
 <a name="numRegions">
@@ -980,7 +1006,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>numRegions</h4>
-<pre>int <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#line.106">numRegions</a></pre>
+<pre>int <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#line.110">numRegions</a></pre>
 </li>
 </ul>
 <a name="numMovedRegions">
@@ -989,7 +1015,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>numMovedRegions</h4>
-<pre>int <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#line.108">numMovedRegions</a></pre>
+<pre>int <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#line.112">numMovedRegions</a></pre>
 </li>
 </ul>
 <a name="clusterState">
@@ -998,7 +1024,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>clusterState</h4>
-<pre><a href="https://docs.oracle.com/javase/8/docs/api/java/util/Map.html?is-external=true" title="class or interface in java.util">Map</a>&lt;<a href="../../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>,<a href="https://docs.oracle.com/javase/8/docs/api/java/util/List.html?is-external=true" title="class or interface in java.util">List</a>&lt;<a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="i [...]
+<pre><a href="https://docs.oracle.com/javase/8/docs/api/java/util/Map.html?is-external=true" title="class or interface in java.util">Map</a>&lt;<a href="../../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>,<a href="https://docs.oracle.com/javase/8/docs/api/java/util/List.html?is-external=true" title="class or interface in java.util">List</a>&lt;<a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="i [...]
 </li>
 </ul>
 <a name="rackManager">
@@ -1007,7 +1033,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>rackManager</h4>
-<pre>private final&nbsp;<a href="../../../../../../org/apache/hadoop/hbase/master/RackManager.html" title="class in org.apache.hadoop.hbase.master">RackManager</a> <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#line.111">rackManager</a></pre>
+<pre>private final&nbsp;<a href="../../../../../../org/apache/hadoop/hbase/master/RackManager.html" title="class in org.apache.hadoop.hbase.master">RackManager</a> <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#line.115">rackManager</a></pre>
 </li>
 </ul>
 <a name="rackLocalities">
@@ -1016,7 +1042,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>rackLocalities</h4>
-<pre>private&nbsp;float[][] <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#line.113">rackLocalities</a></pre>
+<pre>private&nbsp;float[][] <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#line.117">rackLocalities</a></pre>
 </li>
 </ul>
 <a name="regionsToMostLocalEntities">
@@ -1025,7 +1051,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>regionsToMostLocalEntities</h4>
-<pre>private&nbsp;int[][] <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#line.115">regionsToMostLocalEntities</a></pre>
+<pre>private&nbsp;int[][] <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#line.119">regionsToMostLocalEntities</a></pre>
 </li>
 </ul>
 <a name="numRegionsComparator">
@@ -1034,7 +1060,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockListLast">
 <li class="blockList">
 <h4>numRegionsComparator</h4>
-<pre>private&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/util/Comparator.html?is-external=true" title="class or interface in java.util">Comparator</a>&lt;<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Integer.html?is-external=true" title="class or interface in java.lang">Integer</a>&gt; <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#line.800">numRegionsComparator</a></pre>
+<pre>private&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/util/Comparator.html?is-external=true" title="class or interface in java.util">Comparator</a>&lt;<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Integer.html?is-external=true" title="class or interface in java.lang">Integer</a>&gt; <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#line.793">numRegionsComparator</a></pre>
 </li>
 </ul>
 </li>
@@ -1051,7 +1077,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>BalancerClusterState</h4>
-<pre><a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#line.124">BalancerClusterState</a>(<a href="https://docs.oracle.com/javase/8/docs/api/java/util/Map.html?is-external=true" title="class or interface in java.util">Map</a>&lt;<a href="../../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>,<a href="https://docs.oracle.com/javase/8/docs/api/java/util/List.html?is-external=true [...]
+<pre><a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#line.128">BalancerClusterState</a>(<a href="https://docs.oracle.com/javase/8/docs/api/java/util/Map.html?is-external=true" title="class or interface in java.util">Map</a>&lt;<a href="../../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>,<a href="https://docs.oracle.com/javase/8/docs/api/java/util/List.html?is-external=true [...]
                      <a href="https://docs.oracle.com/javase/8/docs/api/java/util/Map.html?is-external=true" title="class or interface in java.util">Map</a>&lt;<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a>,<a href="https://docs.oracle.com/javase/8/docs/api/java/util/Deque.html?is-external=true" title="class or interface in java.util">Deque</a>&lt;<a href="../../../../../../org/apache/hadoop/hb [...]
                      <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/RegionHDFSBlockLocationFinder.html" title="class in org.apache.hadoop.hbase.master.balancer">RegionHDFSBlockLocationFinder</a>&nbsp;regionFinder,
                      <a href="../../../../../../org/apache/hadoop/hbase/master/RackManager.html" title="class in org.apache.hadoop.hbase.master">RackManager</a>&nbsp;rackManager)</pre>
@@ -1063,7 +1089,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockListLast">
 <li class="blockList">
 <h4>BalancerClusterState</h4>
-<pre><a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#line.131">BalancerClusterState</a>(<a href="https://docs.oracle.com/javase/8/docs/api/java/util/Collection.html?is-external=true" title="class or interface in java.util">Collection</a>&lt;<a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&gt;&nbsp;unassignedRegions,
+<pre><a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#line.135">BalancerClusterState</a>(<a href="https://docs.oracle.com/javase/8/docs/api/java/util/Collection.html?is-external=true" title="class or interface in java.util">Collection</a>&lt;<a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&gt;&nbsp;unassignedRegions,
                      <a href="https://docs.oracle.com/javase/8/docs/api/java/util/Map.html?is-external=true" title="class or interface in java.util">Map</a>&lt;<a href="../../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>,<a href="https://docs.oracle.com/javase/8/docs/api/java/util/List.html?is-external=true" title="class or interface in java.util">List</a>&lt;<a href="../../../../../../org/apache/hadoop/hbase/client/RegionInf [...]
                      <a href="https://docs.oracle.com/javase/8/docs/api/java/util/Map.html?is-external=true" title="class or interface in java.util">Map</a>&lt;<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a>,<a href="https://docs.oracle.com/javase/8/docs/api/java/util/Deque.html?is-external=true" title="class or interface in java.util">Deque</a>&lt;<a href="../../../../../../org/apache/hadoop/hb [...]
                      <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/RegionHDFSBlockLocationFinder.html" title="class in org.apache.hadoop.hbase.master.balancer">RegionHDFSBlockLocationFinder</a>&nbsp;regionFinder,
@@ -1078,13 +1104,24 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <!--   -->
 </a>
 <h3>Method Detail</h3>
+<a name="populateRegionPerLocationFromServer-int:A:A-org.agrona.collections.Int2IntCounterMap:A-int:A:A-">
+<!--   -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>populateRegionPerLocationFromServer</h4>
+<pre>private&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#line.370">populateRegionPerLocationFromServer</a>(int[][]&nbsp;regionsPerLocation,
+                                                 org.agrona.collections.Int2IntCounterMap[]&nbsp;colocatedReplicaCountsPerLocation,
+                                                 int[][]&nbsp;serversPerLocation)</pre>
+</li>
+</ul>
 <a name="registerRegion-org.apache.hadoop.hbase.client.RegionInfo-int-int-java.util.Map-org.apache.hadoop.hbase.master.balancer.RegionHDFSBlockLocationFinder-">
 <!--   -->
 </a>
 <ul class="blockList">
 <li class="blockList">
 <h4>registerRegion</h4>
-<pre>private&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#line.409">registerRegion</a>(<a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;region,
+<pre>private&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#line.399">registerRegion</a>(<a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;region,
                             int&nbsp;regionIndex,
                             int&nbsp;serverIndex,
                             <a href="https://docs.oracle.com/javase/8/docs/api/java/util/Map.html?is-external=true" title="class or interface in java.util">Map</a>&lt;<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a>,<a href="https://docs.oracle.com/javase/8/docs/api/java/util/Deque.html?is-external=true" title="class or interface in java.util">Deque</a>&lt;<a href="../../../../../../org/apache/ha [...]
@@ -1098,7 +1135,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>serverHasTooFewRegions</h4>
-<pre>public&nbsp;boolean&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#line.450">serverHasTooFewRegions</a>(int&nbsp;server)</pre>
+<pre>public&nbsp;boolean&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#line.440">serverHasTooFewRegions</a>(int&nbsp;server)</pre>
 <div class="block">Returns true iff a given server has less regions than the balanced amount</div>
 </li>
 </ul>
@@ -1108,7 +1145,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>getOrComputeRackLocalities</h4>
-<pre>public&nbsp;float[][]&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#line.460">getOrComputeRackLocalities</a>()</pre>
+<pre>public&nbsp;float[][]&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#line.450">getOrComputeRackLocalities</a>()</pre>
 <div class="block">Retrieves and lazily initializes a field storing the locality of every region/server
  combination</div>
 </li>
@@ -1119,7 +1156,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>getOrComputeRegionsToMostLocalEntities</h4>
-<pre>public&nbsp;int[]&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#line.471">getOrComputeRegionsToMostLocalEntities</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BalancerClusterState.LocalityType.html" title="enum in org.apache.hadoop.hbase.master.balancer">BalancerClusterState.LocalityType</a>&nbsp;type)</pre>
+<pre>public&nbsp;int[]&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#line.461">getOrComputeRegionsToMostLocalEntities</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BalancerClusterState.LocalityType.html" title="enum in org.apache.hadoop.hbase.master.balancer">BalancerClusterState.LocalityType</a>&nbsp;type)</pre>
 <div class="block">Lazily initializes and retrieves a mapping of region -> server for which region has the highest
  the locality</div>
 </li>
@@ -1130,7 +1167,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>getOrComputeLocality</h4>
-<pre>public&nbsp;float&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#line.481">getOrComputeLocality</a>(int&nbsp;region,
+<pre>public&nbsp;float&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#line.471">getOrComputeLocality</a>(int&nbsp;region,
                                   int&nbsp;entity,
                                   <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BalancerClusterState.LocalityType.html" title="enum in org.apache.hadoop.hbase.master.balancer">BalancerClusterState.LocalityType</a>&nbsp;type)</pre>
 <div class="block">Looks up locality from cache of localities. Will create cache if it does not already exist.</div>
@@ -1142,7 +1179,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>getOrComputeWeightedLocality</h4>
-<pre>public&nbsp;double&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#line.497">getOrComputeWeightedLocality</a>(int&nbsp;region,
+<pre>public&nbsp;double&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#line.487">getOrComputeWeightedLocality</a>(int&nbsp;region,
                                            int&nbsp;server,
                                            <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BalancerClusterState.LocalityType.html" title="enum in org.apache.hadoop.hbase.master.balancer">BalancerClusterState.LocalityType</a>&nbsp;type)</pre>
 <div class="block">Returns locality weighted by region size in MB. Will create locality cache if it does not
@@ -1155,7 +1192,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>getRegionSizeMB</h4>
-<pre>public&nbsp;int&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#line.505">getRegionSizeMB</a>(int&nbsp;region)</pre>
+<pre>public&nbsp;int&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#line.495">getRegionSizeMB</a>(int&nbsp;region)</pre>
 <div class="block">Returns the size in MB from the most recent RegionLoad for region</div>
 </li>
 </ul>
@@ -1165,7 +1202,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>computeCachedLocalities</h4>
-<pre>private&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#line.519">computeCachedLocalities</a>()</pre>
+<pre>private&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#line.509">computeCachedLocalities</a>()</pre>
 <div class="block">Computes and caches the locality for each region/rack combinations, as well as storing a
  mapping of region -> server and region -> rack such that server and rack have the highest
  locality for region</div>
@@ -1177,7 +1214,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>getRackForRegion</h4>
-<pre>public&nbsp;int&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#line.559">getRackForRegion</a>(int&nbsp;region)</pre>
+<pre>public&nbsp;int&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#line.549">getRackForRegion</a>(int&nbsp;region)</pre>
 <div class="block">Maps region index to rack index</div>
 </li>
 </ul>
@@ -1187,7 +1224,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>doAction</h4>
-<pre>public&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#line.567">doAction</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BalanceAction.html" title="class in org.apache.hadoop.hbase.master.balancer">BalanceAction</a>&nbsp;action)</pre>
+<pre>public&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#line.557">doAction</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BalanceAction.html" title="class in org.apache.hadoop.hbase.master.balancer">BalanceAction</a>&nbsp;action)</pre>
 </li>
 </ul>
 <a name="wouldLowerAvailability-org.apache.hadoop.hbase.client.RegionInfo-org.apache.hadoop.hbase.ServerName-">
@@ -1196,7 +1233,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>wouldLowerAvailability</h4>
-<pre>boolean&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#line.608">wouldLowerAvailability</a>(<a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;regionInfo,
+<pre>boolean&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#line.598">wouldLowerAvailability</a>(<a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;regionInfo,
                                <a href="../../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>&nbsp;serverName)</pre>
 <div class="block">Return true if the placement of region on server would lower the availability of the region in
  question</div>
@@ -1206,13 +1243,32 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 </dl>
 </li>
 </ul>
+<a name="checkLocationForPrimary-int-org.agrona.collections.Int2IntCounterMap:A-int-">
+<!--   -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>checkLocationForPrimary</h4>
+<pre>private&nbsp;int&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#line.651">checkLocationForPrimary</a>(int&nbsp;location,
+                                    org.agrona.collections.Int2IntCounterMap[]&nbsp;colocatedReplicaCountsPerLocation,
+                                    int&nbsp;primary)</pre>
+<div class="block">Common method for better solution check.</div>
+<dl>
+<dt><span class="paramLabel">Parameters:</span></dt>
+<dd><code>colocatedReplicaCountsPerLocation</code> - colocatedReplicaCountsPerHost or
+                                          colocatedReplicaCountsPerRack</dd>
+<dt><span class="returnLabel">Returns:</span></dt>
+<dd>1 for better, -1 for no better, 0 for unknown</dd>
+</dl>
+</li>
+</ul>
 <a name="doAssignRegion-org.apache.hadoop.hbase.client.RegionInfo-org.apache.hadoop.hbase.ServerName-">
 <!--   -->
 </a>
 <ul class="blockList">
 <li class="blockList">
 <h4>doAssignRegion</h4>
-<pre>void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#line.672">doAssignRegion</a>(<a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;regionInfo,
+<pre>void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#line.665">doAssignRegion</a>(<a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;regionInfo,
                     <a href="../../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>&nbsp;serverName)</pre>
 </li>
 </ul>
@@ -1222,18 +1278,41 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>regionMoved</h4>
-<pre>void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#line.681">regionMoved</a>(int&nbsp;region,
+<pre>void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#line.674">regionMoved</a>(int&nbsp;region,
                  int&nbsp;oldServer,
                  int&nbsp;newServer)</pre>
 </li>
 </ul>
+<a name="updateForLocation-int:A-int:A:A-org.agrona.collections.Int2IntCounterMap:A-int-int-int-int-">
+<!--   -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>updateForLocation</h4>
+<pre>private&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#line.718">updateForLocation</a>(int[]&nbsp;serverIndexToLocation,
+                               int[][]&nbsp;regionsPerLocation,
+                               org.agrona.collections.Int2IntCounterMap[]&nbsp;colocatedReplicaCountsPerLocation,
+                               int&nbsp;oldServer,
+                               int&nbsp;newServer,
+                               int&nbsp;primary,
+                               int&nbsp;region)</pre>
+<div class="block">Common method for per host and per Location region index updates when a region is moved.</div>
+<dl>
+<dt><span class="paramLabel">Parameters:</span></dt>
+<dd><code>serverIndexToLocation</code> - serverIndexToHostIndex or serverIndexToLocationIndex</dd>
+<dd><code>regionsPerLocation</code> - regionsPerHost or regionsPerLocation</dd>
+<dd><code>colocatedReplicaCountsPerLocation</code> - colocatedReplicaCountsPerHost or
+                                          colocatedReplicaCountsPerRack</dd>
+</dl>
+</li>
+</ul>
 <a name="removeRegion-int:A-int-">
 <!--   -->
 </a>
 <ul class="blockList">
 <li class="blockList">
 <h4>removeRegion</h4>
-<pre>int[]&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#line.741">removeRegion</a>(int[]&nbsp;regions,
+<pre>int[]&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#line.734">removeRegion</a>(int[]&nbsp;regions,
                    int&nbsp;regionIndex)</pre>
 </li>
 </ul>
@@ -1243,7 +1322,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>addRegion</h4>
-<pre>int[]&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#line.755">addRegion</a>(int[]&nbsp;regions,
+<pre>int[]&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#line.748">addRegion</a>(int[]&nbsp;regions,
                 int&nbsp;regionIndex)</pre>
 </li>
 </ul>
@@ -1253,7 +1332,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>addRegionSorted</h4>
-<pre>int[]&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#line.762">addRegionSorted</a>(int[]&nbsp;regions,
+<pre>int[]&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#line.755">addRegionSorted</a>(int[]&nbsp;regions,
                       int&nbsp;regionIndex)</pre>
 </li>
 </ul>
@@ -1263,7 +1342,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>replaceRegion</h4>
-<pre>int[]&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#line.777">replaceRegion</a>(int[]&nbsp;regions,
+<pre>int[]&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#line.770">replaceRegion</a>(int[]&nbsp;regions,
                     int&nbsp;regionIndex,
                     int&nbsp;newRegionIndex)</pre>
 </li>
@@ -1274,7 +1353,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>sortServersByRegionCount</h4>
-<pre>void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#line.788">sortServersByRegionCount</a>()</pre>
+<pre>void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#line.781">sortServersByRegionCount</a>()</pre>
 </li>
 </ul>
 <a name="getNumRegions-int-">
@@ -1283,7 +1362,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>getNumRegions</h4>
-<pre>int&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#line.792">getNumRegions</a>(int&nbsp;server)</pre>
+<pre>int&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#line.785">getNumRegions</a>(int&nbsp;server)</pre>
 </li>
 </ul>
 <a name="contains-int:A-int-">
@@ -1292,7 +1371,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>contains</h4>
-<pre>boolean&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#line.796">contains</a>(int[]&nbsp;arr,
+<pre>boolean&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#line.789">contains</a>(int[]&nbsp;arr,
                  int&nbsp;val)</pre>
 </li>
 </ul>
@@ -1302,7 +1381,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>getLowestLocalityRegionOnServer</h4>
-<pre>int&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#line.802">getLowestLocalityRegionOnServer</a>(int&nbsp;serverIndex)</pre>
+<pre>int&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#line.795">getLowestLocalityRegionOnServer</a>(int&nbsp;serverIndex)</pre>
 </li>
 </ul>
 <a name="getLocalityOfRegion-int-int-">
@@ -1311,7 +1390,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>getLocalityOfRegion</h4>
-<pre>float&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#line.840">getLocalityOfRegion</a>(int&nbsp;region,
+<pre>float&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#line.833">getLocalityOfRegion</a>(int&nbsp;region,
                           int&nbsp;server)</pre>
 </li>
 </ul>
@@ -1321,7 +1400,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>setNumRegions</h4>
-<pre>void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#line.849">setNumRegions</a>(int&nbsp;numRegions)</pre>
+<pre>void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#line.842">setNumRegions</a>(int&nbsp;numRegions)</pre>
 </li>
 </ul>
 <a name="setNumMovedRegions-int-">
@@ -1330,7 +1409,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>setNumMovedRegions</h4>
-<pre>void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#line.853">setNumMovedRegions</a>(int&nbsp;numMovedRegions)</pre>
+<pre>void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#line.846">setNumMovedRegions</a>(int&nbsp;numMovedRegions)</pre>
 </li>
 </ul>
 <a name="toString--">
@@ -1339,7 +1418,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>toString</h4>
-<pre>public&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a>&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#line.858">toString</a>()</pre>
+<pre>public&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a>&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#line.851">toString</a>()</pre>
 <dl>
 <dt><span class="overrideSpecifyLabel">Overrides:</span></dt>
 <dd><code><a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html?is-external=true#toString--" title="class or interface in java.lang">toString</a></code>&nbsp;in class&nbsp;<code><a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">Object</a></code></dd>
@@ -1352,7 +1431,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockListLast">
 <li class="blockList">
 <h4>getSkewChangeFor</h4>
-<pre>private&nbsp;double&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#line.874">getSkewChangeFor</a>(int&nbsp;serverIndex,
+<pre>private&nbsp;double&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#line.867">getSkewChangeFor</a>(int&nbsp;serverIndex,
                                 int&nbsp;tableIndex,
                                 int&nbsp;regionCountChange)</pre>
 </li>
diff --git a/devapidocs/org/apache/hadoop/hbase/master/balancer/RegionReplicaCandidateGenerator.html b/devapidocs/org/apache/hadoop/hbase/master/balancer/RegionReplicaCandidateGenerator.html
index 91c965e..2a4358a 100644
--- a/devapidocs/org/apache/hadoop/hbase/master/balancer/RegionReplicaCandidateGenerator.html
+++ b/devapidocs/org/apache/hadoop/hbase/master/balancer/RegionReplicaCandidateGenerator.html
@@ -119,7 +119,7 @@ var activeTableTab = "activeTableTab";
 <hr>
 <br>
 <pre>@InterfaceAudience.Private
-class <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/RegionReplicaCandidateGenerator.html#line.29">RegionReplicaCandidateGenerator</a>
+class <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/RegionReplicaCandidateGenerator.html#line.32">RegionReplicaCandidateGenerator</a>
 extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/CandidateGenerator.html" title="class in org.apache.hadoop.hbase.master.balancer">CandidateGenerator</a></pre>
 <div class="block">Generates candidates which moves the replicas out of the region server for co-hosted region
  replicas</div>
@@ -183,7 +183,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/Candi
 </tr>
 <tr id="i1" class="rowColor">
 <td class="colFirst"><code>(package private) int</code></td>
-<td class="colLast"><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/RegionReplicaCandidateGenerator.html#selectCoHostedRegionPerGroup-int:A-int:A-int:A-">selectCoHostedRegionPerGroup</a></span>(int[]&nbsp;primariesOfRegionsPerGroup,
+<td class="colLast"><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/RegionReplicaCandidateGenerator.html#selectCoHostedRegionPerGroup-org.agrona.collections.Int2IntCounterMap-int:A-int:A-">selectCoHostedRegionPerGroup</a></span>(org.agrona.collections.Int2IntCounterMap&nbsp;colocatedReplicaCountsPerGroup,
                             int[]&nbsp;regionsPerGroup,
                             int[]&nbsp;regionIndexToPrimaryIndex)</code>
 <div class="block">Randomly select one regionIndex out of all region replicas co-hosted in the same group (a group
@@ -225,7 +225,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/Candi
 <ul class="blockListLast">
 <li class="blockList">
 <h4>randomGenerator</h4>
-<pre>protected final&nbsp;<a href="../../../../../../org/apache/hadoop/hbase/master/balancer/RandomCandidateGenerator.html" title="class in org.apache.hadoop.hbase.master.balancer">RandomCandidateGenerator</a> <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/RegionReplicaCandidateGenerator.html#line.31">randomGenerator</a></pre>
+<pre>protected final&nbsp;<a href="../../../../../../org/apache/hadoop/hbase/master/balancer/RandomCandidateGenerator.html" title="class in org.apache.hadoop.hbase.master.balancer">RandomCandidateGenerator</a> <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/RegionReplicaCandidateGenerator.html#line.34">randomGenerator</a></pre>
 </li>
 </ul>
 </li>
@@ -242,7 +242,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/Candi
 <ul class="blockListLast">
 <li class="blockList">
 <h4>RegionReplicaCandidateGenerator</h4>
-<pre><a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/RegionReplicaCandidateGenerator.html#line.29">RegionReplicaCandidateGenerator</a>()</pre>
+<pre><a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/RegionReplicaCandidateGenerator.html#line.32">RegionReplicaCandidateGenerator</a>()</pre>
 </li>
 </ul>
 </li>
@@ -253,21 +253,21 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/Candi
 <!--   -->
 </a>
 <h3>Method Detail</h3>
-<a name="selectCoHostedRegionPerGroup-int:A-int:A-int:A-">
+<a name="selectCoHostedRegionPerGroup-org.agrona.collections.Int2IntCounterMap-int:A-int:A-">
 <!--   -->
 </a>
 <ul class="blockList">
 <li class="blockList">
 <h4>selectCoHostedRegionPerGroup</h4>
-<pre>int&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/RegionReplicaCandidateGenerator.html#line.42">selectCoHostedRegionPerGroup</a>(int[]&nbsp;primariesOfRegionsPerGroup,
+<pre>int&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/RegionReplicaCandidateGenerator.html#line.45">selectCoHostedRegionPerGroup</a>(org.agrona.collections.Int2IntCounterMap&nbsp;colocatedReplicaCountsPerGroup,
                                  int[]&nbsp;regionsPerGroup,
                                  int[]&nbsp;regionIndexToPrimaryIndex)</pre>
 <div class="block">Randomly select one regionIndex out of all region replicas co-hosted in the same group (a group
  is a server, host or rack)</div>
 <dl>
 <dt><span class="paramLabel">Parameters:</span></dt>
-<dd><code>primariesOfRegionsPerGroup</code> - either Cluster.primariesOfRegionsPerServer,
-          primariesOfRegionsPerHost or primariesOfRegionsPerRack</dd>
+<dd><code>colocatedReplicaCountsPerGroup</code> - either Cluster.colocatedReplicaCountsPerServer,
+          colocatedReplicaCountsPerHost or colocatedReplicaCountsPerRack</dd>
 <dd><code>regionsPerGroup</code> - either Cluster.regionsPerServer, regionsPerHost or regionsPerRack</dd>
 <dd><code>regionIndexToPrimaryIndex</code> - Cluster.regionsIndexToPrimaryIndex</dd>
 <dt><span class="returnLabel">Returns:</span></dt>
@@ -281,7 +281,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/Candi
 <ul class="blockListLast">
 <li class="blockList">
 <h4>generate</h4>
-<pre><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BalanceAction.html" title="class in org.apache.hadoop.hbase.master.balancer">BalanceAction</a>&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/RegionReplicaCandidateGenerator.html#line.84">generate</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html" title="class in org.apache.hadoop.hbase.master.balancer">BalancerClusterState</a>&nbsp;clus [...]
+<pre><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BalanceAction.html" title="class in org.apache.hadoop.hbase.master.balancer">BalanceAction</a>&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/RegionReplicaCandidateGenerator.html#line.72">generate</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html" title="class in org.apache.hadoop.hbase.master.balancer">BalancerClusterState</a>&nbsp;clus [...]
 <dl>
 <dt><span class="overrideSpecifyLabel">Specified by:</span></dt>
 <dd><code><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/CandidateGenerator.html#generate-org.apache.hadoop.hbase.master.balancer.BalancerClusterState-">generate</a></code>&nbsp;in class&nbsp;<code><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/CandidateGenerator.html" title="class in org.apache.hadoop.hbase.master.balancer">CandidateGenerator</a></code></dd>
diff --git a/devapidocs/org/apache/hadoop/hbase/master/balancer/RegionReplicaGroupingCostFunction.html b/devapidocs/org/apache/hadoop/hbase/master/balancer/RegionReplicaGroupingCostFunction.html
index a1d516d..7504e51 100644
--- a/devapidocs/org/apache/hadoop/hbase/master/balancer/RegionReplicaGroupingCostFunction.html
+++ b/devapidocs/org/apache/hadoop/hbase/master/balancer/RegionReplicaGroupingCostFunction.html
@@ -119,7 +119,7 @@ var activeTableTab = "activeTableTab";
 <hr>
 <br>
 <pre>@InterfaceAudience.Private
-abstract class <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/RegionReplicaGroupingCostFunction.html#line.29">RegionReplicaGroupingCostFunction</a>
+abstract class <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/RegionReplicaGroupingCostFunction.html#line.33">RegionReplicaGroupingCostFunction</a>
 extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/CostFunction.html" title="class in org.apache.hadoop.hbase.master.balancer">CostFunction</a></pre>
 <div class="block">A cost function for region replicas. We give a high cost for hosting replicas of the same region
  in the same server, host or rack. We do not prevent the case though, since if numReplicas >
@@ -195,7 +195,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/CostF
 </tr>
 <tr id="i1" class="rowColor">
 <td class="colFirst"><code>protected long</code></td>
-<td class="colLast"><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/RegionReplicaGroupingCostFunction.html#costPerGroup-int:A-">costPerGroup</a></span>(int[]&nbsp;primariesOfRegions)</code>
+<td class="colLast"><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/RegionReplicaGroupingCostFunction.html#costPerGroup-org.agrona.collections.Int2IntCounterMap-">costPerGroup</a></span>(org.agrona.collections.Int2IntCounterMap&nbsp;colocatedReplicaCounts)</code>
 <div class="block">For each primary region, it computes the total number of replicas in the array (numReplicas)
  and returns a sum of numReplicas-1 squared.</div>
 </td>
@@ -254,7 +254,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/CostF
 <ul class="blockList">
 <li class="blockList">
 <h4>maxCost</h4>
-<pre>protected&nbsp;long <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/RegionReplicaGroupingCostFunction.html#line.31">maxCost</a></pre>
+<pre>protected&nbsp;long <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/RegionReplicaGroupingCostFunction.html#line.34">maxCost</a></pre>
 </li>
 </ul>
 <a name="costsPerGroup">
@@ -263,7 +263,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/CostF
 <ul class="blockListLast">
 <li class="blockList">
 <h4>costsPerGroup</h4>
-<pre>protected&nbsp;long[] <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/RegionReplicaGroupingCostFunction.html#line.32">costsPerGroup</a></pre>
+<pre>protected&nbsp;long[] <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/RegionReplicaGroupingCostFunction.html#line.35">costsPerGroup</a></pre>
 </li>
 </ul>
 </li>
@@ -280,7 +280,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/CostF
 <ul class="blockListLast">
 <li class="blockList">
 <h4>RegionReplicaGroupingCostFunction</h4>
-<pre><a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/RegionReplicaGroupingCostFunction.html#line.29">RegionReplicaGroupingCostFunction</a>()</pre>
+<pre><a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/RegionReplicaGroupingCostFunction.html#line.33">RegionReplicaGroupingCostFunction</a>()</pre>
 </li>
 </ul>
 </li>
@@ -297,7 +297,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/CostF
 <ul class="blockList">
 <li class="blockList">
 <h4>prepare</h4>
-<pre>final&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/RegionReplicaGroupingCostFunction.html#line.35">prepare</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html" title="class in org.apache.hadoop.hbase.master.balancer">BalancerClusterState</a>&nbsp;cluster)</pre>
+<pre>final&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/RegionReplicaGroupingCostFunction.html#line.38">prepare</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html" title="class in org.apache.hadoop.hbase.master.balancer">BalancerClusterState</a>&nbsp;cluster)</pre>
 <div class="block"><span class="descfrmTypeLabel">Description copied from class:&nbsp;<code><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/CostFunction.html#prepare-org.apache.hadoop.hbase.master.balancer.BalancerClusterState-">CostFunction</a></code></span></div>
 <div class="block">Called once per LB invocation to give the cost function to initialize it's state, and perform
  any costly calculation.</div>
@@ -313,7 +313,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/CostF
 <ul class="blockList">
 <li class="blockList">
 <h4>loadCosts</h4>
-<pre>protected abstract&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/RegionReplicaGroupingCostFunction.html#line.43">loadCosts</a>()</pre>
+<pre>protected abstract&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/RegionReplicaGroupingCostFunction.html#line.46">loadCosts</a>()</pre>
 </li>
 </ul>
 <a name="getMaxCost-org.apache.hadoop.hbase.master.balancer.BalancerClusterState-">
@@ -322,7 +322,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/CostF
 <ul class="blockList">
 <li class="blockList">
 <h4>getMaxCost</h4>
-<pre>protected final&nbsp;long&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/RegionReplicaGroupingCostFunction.html#line.45">getMaxCost</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html" title="class in org.apache.hadoop.hbase.master.balancer">BalancerClusterState</a>&nbsp;cluster)</pre>
+<pre>protected final&nbsp;long&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/RegionReplicaGroupingCostFunction.html#line.48">getMaxCost</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html" title="class in org.apache.hadoop.hbase.master.balancer">BalancerClusterState</a>&nbsp;cluster)</pre>
 </li>
 </ul>
 <a name="isNeeded--">
@@ -331,7 +331,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/CostF
 <ul class="blockList">
 <li class="blockList">
 <h4>isNeeded</h4>
-<pre>boolean&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/RegionReplicaGroupingCostFunction.html#line.58">isNeeded</a>()</pre>
+<pre>boolean&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/RegionReplicaGroupingCostFunction.html#line.60">isNeeded</a>()</pre>
 <dl>
 <dt><span class="overrideSpecifyLabel">Overrides:</span></dt>
 <dd><code><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/CostFunction.html#isNeeded--">isNeeded</a></code>&nbsp;in class&nbsp;<code><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/CostFunction.html" title="class in org.apache.hadoop.hbase.master.balancer">CostFunction</a></code></dd>
@@ -344,27 +344,27 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/CostF
 <ul class="blockList">
 <li class="blockList">
 <h4>cost</h4>
-<pre>protected&nbsp;double&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/RegionReplicaGroupingCostFunction.html#line.63">cost</a>()</pre>
+<pre>protected&nbsp;double&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/RegionReplicaGroupingCostFunction.html#line.65">cost</a>()</pre>
 <dl>
 <dt><span class="overrideSpecifyLabel">Specified by:</span></dt>
 <dd><code><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/CostFunction.html#cost--">cost</a></code>&nbsp;in class&nbsp;<code><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/CostFunction.html" title="class in org.apache.hadoop.hbase.master.balancer">CostFunction</a></code></dd>
 </dl>
 </li>
 </ul>
-<a name="costPerGroup-int:A-">
+<a name="costPerGroup-org.agrona.collections.Int2IntCounterMap-">
 <!--   -->
 </a>
 <ul class="blockListLast">
 <li class="blockList">
 <h4>costPerGroup</h4>
-<pre>protected final&nbsp;long&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/RegionReplicaGroupingCostFunction.html#line.83">costPerGroup</a>(int[]&nbsp;primariesOfRegions)</pre>
+<pre>protected final&nbsp;long&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/RegionReplicaGroupingCostFunction.html#line.85">costPerGroup</a>(org.agrona.collections.Int2IntCounterMap&nbsp;colocatedReplicaCounts)</pre>
 <div class="block">For each primary region, it computes the total number of replicas in the array (numReplicas)
  and returns a sum of numReplicas-1 squared. For example, if the server hosts regions a, b, c,
  d, e, f where a and b are same replicas, and c,d,e are same replicas, it returns (2-1) * (2-1)
  + (3-1) * (3-1) + (1-1) * (1-1).</div>
 <dl>
 <dt><span class="paramLabel">Parameters:</span></dt>
-<dd><code>primariesOfRegions</code> - a sorted array of primary regions ids for the regions hosted</dd>
+<dd><code>colocatedReplicaCounts</code> - a sorted array of primary regions ids for the regions hosted</dd>
 <dt><span class="returnLabel">Returns:</span></dt>
 <dd>a sum of numReplicas-1 squared for each primary region in the group.</dd>
 </dl>
diff --git a/devapidocs/org/apache/hadoop/hbase/master/balancer/RegionReplicaHostCostFunction.html b/devapidocs/org/apache/hadoop/hbase/master/balancer/RegionReplicaHostCostFunction.html
index b812865..d9dd9bf 100644
--- a/devapidocs/org/apache/hadoop/hbase/master/balancer/RegionReplicaHostCostFunction.html
+++ b/devapidocs/org/apache/hadoop/hbase/master/balancer/RegionReplicaHostCostFunction.html
@@ -120,7 +120,7 @@ var activeTableTab = "activeTableTab";
 <hr>
 <br>
 <pre>@InterfaceAudience.Private
-class <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/RegionReplicaHostCostFunction.html#line.29">RegionReplicaHostCostFunction</a>
+class <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/RegionReplicaHostCostFunction.html#line.30">RegionReplicaHostCostFunction</a>
 extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/RegionReplicaGroupingCostFunction.html" title="class in org.apache.hadoop.hbase.master.balancer">RegionReplicaGroupingCostFunction</a></pre>
 <div class="block">A cost function for region replicas. We give a very high cost to hosting replicas of the same
  region in the same host. We do not prevent the case though, since if numReplicas >
@@ -144,12 +144,12 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/Regio
 <th class="colLast" scope="col">Field and Description</th>
 </tr>
 <tr class="altColor">
-<td class="colFirst"><code>private static float</code></td>
-<td class="colLast"><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/RegionReplicaHostCostFunction.html#DEFAULT_REGION_REPLICA_HOST_COST_KEY">DEFAULT_REGION_REPLICA_HOST_COST_KEY</a></span></code>&nbsp;</td>
+<td class="colFirst"><code>private org.agrona.collections.Int2IntCounterMap[]</code></td>
+<td class="colLast"><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/RegionReplicaHostCostFunction.html#colocatedReplicaCountsPerGroup">colocatedReplicaCountsPerGroup</a></span></code>&nbsp;</td>
 </tr>
 <tr class="rowColor">
-<td class="colFirst"><code>private int[][]</code></td>
-<td class="colLast"><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/RegionReplicaHostCostFunction.html#primariesOfRegionsPerGroup">primariesOfRegionsPerGroup</a></span></code>&nbsp;</td>
+<td class="colFirst"><code>private static float</code></td>
+<td class="colLast"><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/RegionReplicaHostCostFunction.html#DEFAULT_REGION_REPLICA_HOST_COST_KEY">DEFAULT_REGION_REPLICA_HOST_COST_KEY</a></span></code>&nbsp;</td>
 </tr>
 <tr class="altColor">
 <td class="colFirst"><code>private static <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a></code></td>
@@ -217,7 +217,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/Regio
 <!--   -->
 </a>
 <h3>Methods inherited from class&nbsp;org.apache.hadoop.hbase.master.balancer.<a href="../../../../../../org/apache/hadoop/hbase/master/balancer/RegionReplicaGroupingCostFunction.html" title="class in org.apache.hadoop.hbase.master.balancer">RegionReplicaGroupingCostFunction</a></h3>
-<code><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/RegionReplicaGroupingCostFunction.html#cost--">cost</a>, <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/RegionReplicaGroupingCostFunction.html#costPerGroup-int:A-">costPerGroup</a>, <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/RegionReplicaGroupingCostFunction.html#getMaxCost-org.apache.hadoop.hbase.master.balancer.BalancerClusterState-">getMaxCost</a>, <a href="../../../../ [...]
+<code><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/RegionReplicaGroupingCostFunction.html#cost--">cost</a>, <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/RegionReplicaGroupingCostFunction.html#costPerGroup-org.agrona.collections.Int2IntCounterMap-">costPerGroup</a>, <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/RegionReplicaGroupingCostFunction.html#getMaxCost-org.apache.hadoop.hbase.master.balancer.BalancerClusterState-">ge [...]
 </ul>
 <ul class="blockList">
 <li class="blockList"><a name="methods.inherited.from.class.org.apache.hadoop.hbase.master.balancer.CostFunction">
@@ -253,7 +253,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/Regio
 <ul class="blockList">
 <li class="blockList">
 <h4>REGION_REPLICA_HOST_COST_KEY</h4>
-<pre>private static final&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a> <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/RegionReplicaHostCostFunction.html#line.31">REGION_REPLICA_HOST_COST_KEY</a></pre>
+<pre>private static final&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a> <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/RegionReplicaHostCostFunction.html#line.32">REGION_REPLICA_HOST_COST_KEY</a></pre>
 <dl>
 <dt><span class="seeLabel">See Also:</span></dt>
 <dd><a href="../../../../../../constant-values.html#org.apache.hadoop.hbase.master.balancer.RegionReplicaHostCostFunction.REGION_REPLICA_HOST_COST_KEY">Constant Field Values</a></dd>
@@ -266,20 +266,20 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/Regio
 <ul class="blockList">
 <li class="blockList">
 <h4>DEFAULT_REGION_REPLICA_HOST_COST_KEY</h4>
-<pre>private static final&nbsp;float <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/RegionReplicaHostCostFunction.html#line.33">DEFAULT_REGION_REPLICA_HOST_COST_KEY</a></pre>
+<pre>private static final&nbsp;float <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/RegionReplicaHostCostFunction.html#line.34">DEFAULT_REGION_REPLICA_HOST_COST_KEY</a></pre>
 <dl>
 <dt><span class="seeLabel">See Also:</span></dt>
 <dd><a href="../../../../../../constant-values.html#org.apache.hadoop.hbase.master.balancer.RegionReplicaHostCostFunction.DEFAULT_REGION_REPLICA_HOST_COST_KEY">Constant Field Values</a></dd>
 </dl>
 </li>
 </ul>
-<a name="primariesOfRegionsPerGroup">
+<a name="colocatedReplicaCountsPerGroup">
 <!--   -->
 </a>
 <ul class="blockListLast">
 <li class="blockList">
-<h4>primariesOfRegionsPerGroup</h4>
-<pre>private&nbsp;int[][] <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/RegionReplicaHostCostFunction.html#line.35">primariesOfRegionsPerGroup</a></pre>
+<h4>colocatedReplicaCountsPerGroup</h4>
+<pre>private&nbsp;org.agrona.collections.Int2IntCounterMap[] <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/RegionReplicaHostCostFunction.html#line.36">colocatedReplicaCountsPerGroup</a></pre>
 </li>
 </ul>
 </li>
@@ -296,7 +296,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/Regio
 <ul class="blockListLast">
 <li class="blockList">
 <h4>RegionReplicaHostCostFunction</h4>
-<pre>public&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/RegionReplicaHostCostFunction.html#line.37">RegionReplicaHostCostFunction</a>(org.apache.hadoop.conf.Configuration&nbsp;conf)</pre>
+<pre>public&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/RegionReplicaHostCostFunction.html#line.38">RegionReplicaHostCostFunction</a>(org.apache.hadoop.conf.Configuration&nbsp;conf)</pre>
 </li>
 </ul>
 </li>
@@ -313,7 +313,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/Regio
 <ul class="blockList">
 <li class="blockList">
 <h4>loadCosts</h4>
-<pre>protected&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/RegionReplicaHostCostFunction.html#line.43">loadCosts</a>()</pre>
+<pre>protected&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/RegionReplicaHostCostFunction.html#line.44">loadCosts</a>()</pre>
 <dl>
 <dt><span class="overrideSpecifyLabel">Specified by:</span></dt>
 <dd><code><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/RegionReplicaGroupingCostFunction.html#loadCosts--">loadCosts</a></code>&nbsp;in class&nbsp;<code><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/RegionReplicaGroupingCostFunction.html" title="class in org.apache.hadoop.hbase.master.balancer">RegionReplicaGroupingCostFunction</a></code></dd>
@@ -326,7 +326,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/Regio
 <ul class="blockListLast">
 <li class="blockList">
 <h4>regionMoved</h4>
-<pre>protected&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/RegionReplicaHostCostFunction.html#line.55">regionMoved</a>(int&nbsp;region,
+<pre>protected&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/RegionReplicaHostCostFunction.html#line.57">regionMoved</a>(int&nbsp;region,
                            int&nbsp;oldServer,
                            int&nbsp;newServer)</pre>
 <dl>
diff --git a/devapidocs/org/apache/hadoop/hbase/master/balancer/RegionReplicaRackCandidateGenerator.html b/devapidocs/org/apache/hadoop/hbase/master/balancer/RegionReplicaRackCandidateGenerator.html
index 4c6f3b5..dab7641 100644
--- a/devapidocs/org/apache/hadoop/hbase/master/balancer/RegionReplicaRackCandidateGenerator.html
+++ b/devapidocs/org/apache/hadoop/hbase/master/balancer/RegionReplicaRackCandidateGenerator.html
@@ -184,7 +184,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/Regio
 <!--   -->
 </a>
 <h3>Methods inherited from class&nbsp;org.apache.hadoop.hbase.master.balancer.<a href="../../../../../../org/apache/hadoop/hbase/master/balancer/RegionReplicaCandidateGenerator.html" title="class in org.apache.hadoop.hbase.master.balancer">RegionReplicaCandidateGenerator</a></h3>
-<code><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/RegionReplicaCandidateGenerator.html#selectCoHostedRegionPerGroup-int:A-int:A-int:A-">selectCoHostedRegionPerGroup</a></code></li>
+<code><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/RegionReplicaCandidateGenerator.html#selectCoHostedRegionPerGroup-org.agrona.collections.Int2IntCounterMap-int:A-int:A-">selectCoHostedRegionPerGroup</a></code></li>
 </ul>
 <ul class="blockList">
 <li class="blockList"><a name="methods.inherited.from.class.org.apache.hadoop.hbase.master.balancer.CandidateGenerator">
diff --git a/devapidocs/org/apache/hadoop/hbase/master/balancer/RegionReplicaRackCostFunction.html b/devapidocs/org/apache/hadoop/hbase/master/balancer/RegionReplicaRackCostFunction.html
index 58ea916..4c1dc99 100644
--- a/devapidocs/org/apache/hadoop/hbase/master/balancer/RegionReplicaRackCostFunction.html
+++ b/devapidocs/org/apache/hadoop/hbase/master/balancer/RegionReplicaRackCostFunction.html
@@ -212,7 +212,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/Regio
 <!--   -->
 </a>
 <h3>Methods inherited from class&nbsp;org.apache.hadoop.hbase.master.balancer.<a href="../../../../../../org/apache/hadoop/hbase/master/balancer/RegionReplicaGroupingCostFunction.html" title="class in org.apache.hadoop.hbase.master.balancer">RegionReplicaGroupingCostFunction</a></h3>
-<code><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/RegionReplicaGroupingCostFunction.html#cost--">cost</a>, <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/RegionReplicaGroupingCostFunction.html#costPerGroup-int:A-">costPerGroup</a>, <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/RegionReplicaGroupingCostFunction.html#getMaxCost-org.apache.hadoop.hbase.master.balancer.BalancerClusterState-">getMaxCost</a>, <a href="../../../../ [...]
+<code><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/RegionReplicaGroupingCostFunction.html#cost--">cost</a>, <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/RegionReplicaGroupingCostFunction.html#costPerGroup-org.agrona.collections.Int2IntCounterMap-">costPerGroup</a>, <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/RegionReplicaGroupingCostFunction.html#getMaxCost-org.apache.hadoop.hbase.master.balancer.BalancerClusterState-">ge [...]
 </ul>
 <ul class="blockList">
 <li class="blockList"><a name="methods.inherited.from.class.org.apache.hadoop.hbase.master.balancer.CostFunction">
diff --git a/devapidocs/org/apache/hadoop/hbase/master/balancer/package-tree.html b/devapidocs/org/apache/hadoop/hbase/master/balancer/package-tree.html
index 55e1874..56a27f7 100644
--- a/devapidocs/org/apache/hadoop/hbase/master/balancer/package-tree.html
+++ b/devapidocs/org/apache/hadoop/hbase/master/balancer/package-tree.html
@@ -212,8 +212,8 @@
 <ul>
 <li type="circle">java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Enum.html?is-external=true" title="class or interface in java.lang"><span class="typeNameLink">Enum</span></a>&lt;E&gt; (implements java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Comparable.html?is-external=true" title="class or interface in java.lang">Comparable</a>&lt;T&gt;, java.io.<a href="https://docs.oracle.com/javase/8/docs/api/java/io/Serializable.html?is-external=true [...]
 <ul>
-<li type="circle">org.apache.hadoop.hbase.master.balancer.<a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BalancerClusterState.LocalityType.html" title="enum in org.apache.hadoop.hbase.master.balancer"><span class="typeNameLink">BalancerClusterState.LocalityType</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.master.balancer.<a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BalanceAction.Type.html" title="enum in org.apache.hadoop.hbase.master.balancer"><span class="typeNameLink">BalanceAction.Type</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.master.balancer.<a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BalancerClusterState.LocalityType.html" title="enum in org.apache.hadoop.hbase.master.balancer"><span class="typeNameLink">BalancerClusterState.LocalityType</span></a></li>
 </ul>
 </li>
 </ul>
diff --git a/devapidocs/org/apache/hadoop/hbase/master/package-tree.html b/devapidocs/org/apache/hadoop/hbase/master/package-tree.html
index 9d608da..45e82bb 100644
--- a/devapidocs/org/apache/hadoop/hbase/master/package-tree.html
+++ b/devapidocs/org/apache/hadoop/hbase/master/package-tree.html
@@ -317,11 +317,11 @@
 <ul>
 <li type="circle">java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Enum.html?is-external=true" title="class or interface in java.lang"><span class="typeNameLink">Enum</span></a>&lt;E&gt; (implements java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Comparable.html?is-external=true" title="class or interface in java.lang">Comparable</a>&lt;T&gt;, java.io.<a href="https://docs.oracle.com/javase/8/docs/api/java/io/Serializable.html?is-external=true [...]
 <ul>
-<li type="circle">org.apache.hadoop.hbase.master.<a href="../../../../../org/apache/hadoop/hbase/master/SplitLogManager.TerminationStatus.html" title="enum in org.apache.hadoop.hbase.master"><span class="typeNameLink">SplitLogManager.TerminationStatus</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.master.<a href="../../../../../org/apache/hadoop/hbase/master/ServerManager.ServerLiveState.html" title="enum in org.apache.hadoop.hbase.master"><span class="typeNameLink">ServerManager.ServerLiveState</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.master.<a href="../../../../../org/apache/hadoop/hbase/master/SplitLogManager.ResubmitDirective.html" title="enum in org.apache.hadoop.hbase.master"><span class="typeNameLink">SplitLogManager.ResubmitDirective</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.master.<a href="../../../../../org/apache/hadoop/hbase/master/MasterRpcServices.BalanceSwitchMode.html" title="enum in org.apache.hadoop.hbase.master"><span class="typeNameLink">MasterRpcServices.BalanceSwitchMode</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.master.<a href="../../../../../org/apache/hadoop/hbase/master/ServerManager.ServerLiveState.html" title="enum in org.apache.hadoop.hbase.master"><span class="typeNameLink">ServerManager.ServerLiveState</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.master.<a href="../../../../../org/apache/hadoop/hbase/master/RegionState.State.html" title="enum in org.apache.hadoop.hbase.master"><span class="typeNameLink">RegionState.State</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.master.<a href="../../../../../org/apache/hadoop/hbase/master/SplitLogManager.TerminationStatus.html" title="enum in org.apache.hadoop.hbase.master"><span class="typeNameLink">SplitLogManager.TerminationStatus</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.master.<a href="../../../../../org/apache/hadoop/hbase/master/MetricsMasterSourceFactoryImpl.FactoryStorage.html" title="enum in org.apache.hadoop.hbase.master"><span class="typeNameLink">MetricsMasterSourceFactoryImpl.FactoryStorage</span></a></li>
 </ul>
 </li>
diff --git a/devapidocs/org/apache/hadoop/hbase/monitoring/package-tree.html b/devapidocs/org/apache/hadoop/hbase/monitoring/package-tree.html
index 8e1184b..c9ca896 100644
--- a/devapidocs/org/apache/hadoop/hbase/monitoring/package-tree.html
+++ b/devapidocs/org/apache/hadoop/hbase/monitoring/package-tree.html
@@ -126,8 +126,8 @@
 <ul>
 <li type="circle">java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Enum.html?is-external=true" title="class or interface in java.lang"><span class="typeNameLink">Enum</span></a>&lt;E&gt; (implements java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Comparable.html?is-external=true" title="class or interface in java.lang">Comparable</a>&lt;T&gt;, java.io.<a href="https://docs.oracle.com/javase/8/docs/api/java/io/Serializable.html?is-external=true [...]
 <ul>
-<li type="circle">org.apache.hadoop.hbase.monitoring.<a href="../../../../../org/apache/hadoop/hbase/monitoring/MonitoredTask.State.html" title="enum in org.apache.hadoop.hbase.monitoring"><span class="typeNameLink">MonitoredTask.State</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.monitoring.<a href="../../../../../org/apache/hadoop/hbase/monitoring/TaskMonitor.TaskFilter.TaskType.html" title="enum in org.apache.hadoop.hbase.monitoring"><span class="typeNameLink">TaskMonitor.TaskFilter.TaskType</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.monitoring.<a href="../../../../../org/apache/hadoop/hbase/monitoring/MonitoredTask.State.html" title="enum in org.apache.hadoop.hbase.monitoring"><span class="typeNameLink">MonitoredTask.State</span></a></li>
 </ul>
 </li>
 </ul>
diff --git a/devapidocs/org/apache/hadoop/hbase/package-tree.html b/devapidocs/org/apache/hadoop/hbase/package-tree.html
index 75b8507..8b9478e 100644
--- a/devapidocs/org/apache/hadoop/hbase/package-tree.html
+++ b/devapidocs/org/apache/hadoop/hbase/package-tree.html
@@ -464,20 +464,20 @@
 <ul>
 <li type="circle">java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Enum.html?is-external=true" title="class or interface in java.lang"><span class="typeNameLink">Enum</span></a>&lt;E&gt; (implements java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Comparable.html?is-external=true" title="class or interface in java.lang">Comparable</a>&lt;T&gt;, java.io.<a href="https://docs.oracle.com/javase/8/docs/api/java/io/Serializable.html?is-external=true [...]
 <ul>
-<li type="circle">org.apache.hadoop.hbase.<a href="../../../../org/apache/hadoop/hbase/Coprocessor.State.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">Coprocessor.State</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.<a href="../../../../org/apache/hadoop/hbase/HConstants.OperationStatusCode.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">HConstants.OperationStatusCode</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.<a href="../../../../org/apache/hadoop/hbase/KeepDeletedCells.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">KeepDeletedCells</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.<a href="../../../../org/apache/hadoop/hbase/ClientMetaTableAccessor.QueryType.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">ClientMetaTableAccessor.QueryType</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.<a href="../../../../org/apache/hadoop/hbase/KeyValue.Type.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">KeyValue.Type</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.<a href="../../../../org/apache/hadoop/hbase/CompareOperator.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">CompareOperator</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.<a href="../../../../org/apache/hadoop/hbase/HealthChecker.HealthCheckerExitStatus.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">HealthChecker.HealthCheckerExitStatus</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.<a href="../../../../org/apache/hadoop/hbase/MemoryCompactionPolicy.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">MemoryCompactionPolicy</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.<a href="../../../../org/apache/hadoop/hbase/CompatibilitySingletonFactory.SingletonStorage.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">CompatibilitySingletonFactory.SingletonStorage</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.<a href="../../../../org/apache/hadoop/hbase/MetaRegionLocationCache.ZNodeOpType.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">MetaRegionLocationCache.ZNodeOpType</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.<a href="../../../../org/apache/hadoop/hbase/CellBuilderType.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">CellBuilderType</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.<a href="../../../../org/apache/hadoop/hbase/Cell.Type.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">Cell.Type</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.<a href="../../../../org/apache/hadoop/hbase/Size.Unit.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">Size.Unit</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.<a href="../../../../org/apache/hadoop/hbase/ClientMetaTableAccessor.QueryType.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">ClientMetaTableAccessor.QueryType</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.<a href="../../../../org/apache/hadoop/hbase/KeepDeletedCells.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">KeepDeletedCells</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.<a href="../../../../org/apache/hadoop/hbase/CompatibilitySingletonFactory.SingletonStorage.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">CompatibilitySingletonFactory.SingletonStorage</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.<a href="../../../../org/apache/hadoop/hbase/CompareOperator.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">CompareOperator</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.<a href="../../../../org/apache/hadoop/hbase/KeyValue.Type.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">KeyValue.Type</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.<a href="../../../../org/apache/hadoop/hbase/ClusterMetrics.Option.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">ClusterMetrics.Option</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.<a href="../../../../org/apache/hadoop/hbase/Cell.Type.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">Cell.Type</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.<a href="../../../../org/apache/hadoop/hbase/Coprocessor.State.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">Coprocessor.State</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.<a href="../../../../org/apache/hadoop/hbase/MemoryCompactionPolicy.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">MemoryCompactionPolicy</span></a></li>
 </ul>
 </li>
 </ul>
diff --git a/devapidocs/org/apache/hadoop/hbase/procedure2/package-tree.html b/devapidocs/org/apache/hadoop/hbase/procedure2/package-tree.html
index 35af529..4f8b423 100644
--- a/devapidocs/org/apache/hadoop/hbase/procedure2/package-tree.html
+++ b/devapidocs/org/apache/hadoop/hbase/procedure2/package-tree.html
@@ -217,11 +217,11 @@
 <ul>
 <li type="circle">java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Enum.html?is-external=true" title="class or interface in java.lang"><span class="typeNameLink">Enum</span></a>&lt;E&gt; (implements java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Comparable.html?is-external=true" title="class or interface in java.lang">Comparable</a>&lt;T&gt;, java.io.<a href="https://docs.oracle.com/javase/8/docs/api/java/io/Serializable.html?is-external=true [...]
 <ul>
-<li type="circle">org.apache.hadoop.hbase.procedure2.<a href="../../../../../org/apache/hadoop/hbase/procedure2/StateMachineProcedure.Flow.html" title="enum in org.apache.hadoop.hbase.procedure2"><span class="typeNameLink">StateMachineProcedure.Flow</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.procedure2.<a href="../../../../../org/apache/hadoop/hbase/procedure2/Procedure.LockState.html" title="enum in org.apache.hadoop.hbase.procedure2"><span class="typeNameLink">Procedure.LockState</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.procedure2.<a href="../../../../../org/apache/hadoop/hbase/procedure2/LockType.html" title="enum in org.apache.hadoop.hbase.procedure2"><span class="typeNameLink">LockType</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.procedure2.<a href="../../../../../org/apache/hadoop/hbase/procedure2/RootProcedureState.State.html" title="enum in org.apache.hadoop.hbase.procedure2"><span class="typeNameLink">RootProcedureState.State</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.procedure2.<a href="../../../../../org/apache/hadoop/hbase/procedure2/Procedure.LockState.html" title="enum in org.apache.hadoop.hbase.procedure2"><span class="typeNameLink">Procedure.LockState</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.procedure2.<a href="../../../../../org/apache/hadoop/hbase/procedure2/StateMachineProcedure.Flow.html" title="enum in org.apache.hadoop.hbase.procedure2"><span class="typeNameLink">StateMachineProcedure.Flow</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.procedure2.<a href="../../../../../org/apache/hadoop/hbase/procedure2/LockedResourceType.html" title="enum in org.apache.hadoop.hbase.procedure2"><span class="typeNameLink">LockedResourceType</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.procedure2.<a href="../../../../../org/apache/hadoop/hbase/procedure2/LockType.html" title="enum in org.apache.hadoop.hbase.procedure2"><span class="typeNameLink">LockType</span></a></li>
 </ul>
 </li>
 </ul>
diff --git a/devapidocs/org/apache/hadoop/hbase/procedure2/store/wal/package-tree.html b/devapidocs/org/apache/hadoop/hbase/procedure2/store/wal/package-tree.html
index a402ab9..d094b12 100644
--- a/devapidocs/org/apache/hadoop/hbase/procedure2/store/wal/package-tree.html
+++ b/devapidocs/org/apache/hadoop/hbase/procedure2/store/wal/package-tree.html
@@ -133,8 +133,8 @@
 <ul>
 <li type="circle">java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Enum.html?is-external=true" title="class or interface in java.lang"><span class="typeNameLink">Enum</span></a>&lt;E&gt; (implements java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Comparable.html?is-external=true" title="class or interface in java.lang">Comparable</a>&lt;T&gt;, java.io.<a href="https://docs.oracle.com/javase/8/docs/api/java/io/Serializable.html?is-external=true [...]
 <ul>
-<li type="circle">org.apache.hadoop.hbase.procedure2.store.wal.<a href="../../../../../../../org/apache/hadoop/hbase/procedure2/store/wal/ProcedureStoreTracker.DeleteState.html" title="enum in org.apache.hadoop.hbase.procedure2.store.wal"><span class="typeNameLink">ProcedureStoreTracker.DeleteState</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.procedure2.store.wal.<a href="../../../../../../../org/apache/hadoop/hbase/procedure2/store/wal/WALProcedureStore.PushType.html" title="enum in org.apache.hadoop.hbase.procedure2.store.wal"><span class="typeNameLink">WALProcedureStore.PushType</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.procedure2.store.wal.<a href="../../../../../../../org/apache/hadoop/hbase/procedure2/store/wal/ProcedureStoreTracker.DeleteState.html" title="enum in org.apache.hadoop.hbase.procedure2.store.wal"><span class="typeNameLink">ProcedureStoreTracker.DeleteState</span></a></li>
 </ul>
 </li>
 </ul>
diff --git a/devapidocs/org/apache/hadoop/hbase/quotas/package-tree.html b/devapidocs/org/apache/hadoop/hbase/quotas/package-tree.html
index afb6139..8241524 100644
--- a/devapidocs/org/apache/hadoop/hbase/quotas/package-tree.html
+++ b/devapidocs/org/apache/hadoop/hbase/quotas/package-tree.html
@@ -240,12 +240,12 @@
 <ul>
 <li type="circle">java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Enum.html?is-external=true" title="class or interface in java.lang"><span class="typeNameLink">Enum</span></a>&lt;E&gt; (implements java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Comparable.html?is-external=true" title="class or interface in java.lang">Comparable</a>&lt;T&gt;, java.io.<a href="https://docs.oracle.com/javase/8/docs/api/java/io/Serializable.html?is-external=true [...]
 <ul>
+<li type="circle">org.apache.hadoop.hbase.quotas.<a href="../../../../../org/apache/hadoop/hbase/quotas/RpcThrottlingException.Type.html" title="enum in org.apache.hadoop.hbase.quotas"><span class="typeNameLink">RpcThrottlingException.Type</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.quotas.<a href="../../../../../org/apache/hadoop/hbase/quotas/SpaceViolationPolicy.html" title="enum in org.apache.hadoop.hbase.quotas"><span class="typeNameLink">SpaceViolationPolicy</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.quotas.<a href="../../../../../org/apache/hadoop/hbase/quotas/ThrottleType.html" title="enum in org.apache.hadoop.hbase.quotas"><span class="typeNameLink">ThrottleType</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.quotas.<a href="../../../../../org/apache/hadoop/hbase/quotas/QuotaScope.html" title="enum in org.apache.hadoop.hbase.quotas"><span class="typeNameLink">QuotaScope</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.quotas.<a href="../../../../../org/apache/hadoop/hbase/quotas/QuotaType.html" title="enum in org.apache.hadoop.hbase.quotas"><span class="typeNameLink">QuotaType</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.quotas.<a href="../../../../../org/apache/hadoop/hbase/quotas/OperationQuota.OperationType.html" title="enum in org.apache.hadoop.hbase.quotas"><span class="typeNameLink">OperationQuota.OperationType</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.quotas.<a href="../../../../../org/apache/hadoop/hbase/quotas/SpaceViolationPolicy.html" title="enum in org.apache.hadoop.hbase.quotas"><span class="typeNameLink">SpaceViolationPolicy</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.quotas.<a href="../../../../../org/apache/hadoop/hbase/quotas/RpcThrottlingException.Type.html" title="enum in org.apache.hadoop.hbase.quotas"><span class="typeNameLink">RpcThrottlingException.Type</span></a></li>
 </ul>
 </li>
 </ul>
diff --git a/devapidocs/org/apache/hadoop/hbase/regionserver/package-tree.html b/devapidocs/org/apache/hadoop/hbase/regionserver/package-tree.html
index 3171095..387bb2a 100644
--- a/devapidocs/org/apache/hadoop/hbase/regionserver/package-tree.html
+++ b/devapidocs/org/apache/hadoop/hbase/regionserver/package-tree.html
@@ -741,20 +741,20 @@
 <ul>
 <li type="circle">java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Enum.html?is-external=true" title="class or interface in java.lang"><span class="typeNameLink">Enum</span></a>&lt;E&gt; (implements java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Comparable.html?is-external=true" title="class or interface in java.lang">Comparable</a>&lt;T&gt;, java.io.<a href="https://docs.oracle.com/javase/8/docs/api/java/io/Serializable.html?is-external=true [...]
 <ul>
-<li type="circle">org.apache.hadoop.hbase.regionserver.<a href="../../../../../org/apache/hadoop/hbase/regionserver/MemStoreCompactionStrategy.Action.html" title="enum in org.apache.hadoop.hbase.regionserver"><span class="typeNameLink">MemStoreCompactionStrategy.Action</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.regionserver.<a href="../../../../../org/apache/hadoop/hbase/regionserver/ScanType.html" title="enum in org.apache.hadoop.hbase.regionserver"><span class="typeNameLink">ScanType</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.regionserver.<a href="../../../../../org/apache/hadoop/hbase/regionserver/TimeRangeTracker.Type.html" title="enum in org.apache.hadoop.hbase.regionserver"><span class="typeNameLink">TimeRangeTracker.Type</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.regionserver.<a href="../../../../../org/apache/hadoop/hbase/regionserver/DefaultHeapMemoryTuner.StepDirection.html" title="enum in org.apache.hadoop.hbase.regionserver"><span class="typeNameLink">DefaultHeapMemoryTuner.StepDirection</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.regionserver.<a href="../../../../../org/apache/hadoop/hbase/regionserver/FlushType.html" title="enum in org.apache.hadoop.hbase.regionserver"><span class="typeNameLink">FlushType</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.regionserver.<a href="../../../../../org/apache/hadoop/hbase/regionserver/ChunkCreator.ChunkType.html" title="enum in org.apache.hadoop.hbase.regionserver"><span class="typeNameLink">ChunkCreator.ChunkType</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.regionserver.<a href="../../../../../org/apache/hadoop/hbase/regionserver/HRegion.FlushResult.Result.html" title="enum in org.apache.hadoop.hbase.regionserver"><span class="typeNameLink">HRegion.FlushResult.Result</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.regionserver.<a href="../../../../../org/apache/hadoop/hbase/regionserver/Region.Operation.html" title="enum in org.apache.hadoop.hbase.regionserver"><span class="typeNameLink">Region.Operation</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.regionserver.<a href="../../../../../org/apache/hadoop/hbase/regionserver/CompactingMemStore.IndexType.html" title="enum in org.apache.hadoop.hbase.regionserver"><span class="typeNameLink">CompactingMemStore.IndexType</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.regionserver.<a href="../../../../../org/apache/hadoop/hbase/regionserver/ScanType.html" title="enum in org.apache.hadoop.hbase.regionserver"><span class="typeNameLink">ScanType</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.regionserver.<a href="../../../../../org/apache/hadoop/hbase/regionserver/MetricsRegionServerSourceFactoryImpl.FactoryStorage.html" title="enum in org.apache.hadoop.hbase.regionserver"><span class="typeNameLink">MetricsRegionServerSourceFactoryImpl.FactoryStorage</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.regionserver.<a href="../../../../../org/apache/hadoop/hbase/regionserver/MemStoreCompactionStrategy.Action.html" title="enum in org.apache.hadoop.hbase.regionserver"><span class="typeNameLink">MemStoreCompactionStrategy.Action</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.regionserver.<a href="../../../../../org/apache/hadoop/hbase/regionserver/ScannerContext.NextState.html" title="enum in org.apache.hadoop.hbase.regionserver"><span class="typeNameLink">ScannerContext.NextState</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.regionserver.<a href="../../../../../org/apache/hadoop/hbase/regionserver/ScannerContext.LimitScope.html" title="enum in org.apache.hadoop.hbase.regionserver"><span class="typeNameLink">ScannerContext.LimitScope</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.regionserver.<a href="../../../../../org/apache/hadoop/hbase/regionserver/SplitLogWorker.TaskExecutor.Status.html" title="enum in org.apache.hadoop.hbase.regionserver"><span class="typeNameLink">SplitLogWorker.TaskExecutor.Status</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.regionserver.<a href="../../../../../org/apache/hadoop/hbase/regionserver/TimeRangeTracker.Type.html" title="enum in org.apache.hadoop.hbase.regionserver"><span class="typeNameLink">TimeRangeTracker.Type</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.regionserver.<a href="../../../../../org/apache/hadoop/hbase/regionserver/FlushType.html" title="enum in org.apache.hadoop.hbase.regionserver"><span class="typeNameLink">FlushType</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.regionserver.<a href="../../../../../org/apache/hadoop/hbase/regionserver/MetricsRegionServerSourceFactoryImpl.FactoryStorage.html" title="enum in org.apache.hadoop.hbase.regionserver"><span class="typeNameLink">MetricsRegionServerSourceFactoryImpl.FactoryStorage</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.regionserver.<a href="../../../../../org/apache/hadoop/hbase/regionserver/CompactingMemStore.IndexType.html" title="enum in org.apache.hadoop.hbase.regionserver"><span class="typeNameLink">CompactingMemStore.IndexType</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.regionserver.<a href="../../../../../org/apache/hadoop/hbase/regionserver/BloomType.html" title="enum in org.apache.hadoop.hbase.regionserver"><span class="typeNameLink">BloomType</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.regionserver.<a href="../../../../../org/apache/hadoop/hbase/regionserver/ScannerContext.LimitScope.html" title="enum in org.apache.hadoop.hbase.regionserver"><span class="typeNameLink">ScannerContext.LimitScope</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.regionserver.<a href="../../../../../org/apache/hadoop/hbase/regionserver/DefaultHeapMemoryTuner.StepDirection.html" title="enum in org.apache.hadoop.hbase.regionserver"><span class="typeNameLink">DefaultHeapMemoryTuner.StepDirection</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.regionserver.<a href="../../../../../org/apache/hadoop/hbase/regionserver/HRegion.FlushResult.Result.html" title="enum in org.apache.hadoop.hbase.regionserver"><span class="typeNameLink">HRegion.FlushResult.Result</span></a></li>
 </ul>
 </li>
 </ul>
diff --git a/devapidocs/org/apache/hadoop/hbase/regionserver/wal/package-tree.html b/devapidocs/org/apache/hadoop/hbase/regionserver/wal/package-tree.html
index 61f3f12..3639c07 100644
--- a/devapidocs/org/apache/hadoop/hbase/regionserver/wal/package-tree.html
+++ b/devapidocs/org/apache/hadoop/hbase/regionserver/wal/package-tree.html
@@ -249,10 +249,10 @@
 <ul>
 <li type="circle">java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Enum.html?is-external=true" title="class or interface in java.lang"><span class="typeNameLink">Enum</span></a>&lt;E&gt; (implements java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Comparable.html?is-external=true" title="class or interface in java.lang">Comparable</a>&lt;T&gt;, java.io.<a href="https://docs.oracle.com/javase/8/docs/api/java/io/Serializable.html?is-external=true [...]
 <ul>
-<li type="circle">org.apache.hadoop.hbase.regionserver.wal.<a href="../../../../../../org/apache/hadoop/hbase/regionserver/wal/RingBufferTruck.Type.html" title="enum in org.apache.hadoop.hbase.regionserver.wal"><span class="typeNameLink">RingBufferTruck.Type</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.regionserver.wal.<a href="../../../../../../org/apache/hadoop/hbase/regionserver/wal/CompressionContext.DictionaryIndex.html" title="enum in org.apache.hadoop.hbase.regionserver.wal"><span class="typeNameLink">CompressionContext.DictionaryIndex</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.regionserver.wal.<a href="../../../../../../org/apache/hadoop/hbase/regionserver/wal/ProtobufLogReader.WALHdrResult.html" title="enum in org.apache.hadoop.hbase.regionserver.wal"><span class="typeNameLink">ProtobufLogReader.WALHdrResult</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.regionserver.wal.<a href="../../../../../../org/apache/hadoop/hbase/regionserver/wal/WALActionsListener.RollRequestReason.html" title="enum in org.apache.hadoop.hbase.regionserver.wal"><span class="typeNameLink">WALActionsListener.RollRequestReason</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.regionserver.wal.<a href="../../../../../../org/apache/hadoop/hbase/regionserver/wal/ProtobufLogReader.WALHdrResult.html" title="enum in org.apache.hadoop.hbase.regionserver.wal"><span class="typeNameLink">ProtobufLogReader.WALHdrResult</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.regionserver.wal.<a href="../../../../../../org/apache/hadoop/hbase/regionserver/wal/CompressionContext.DictionaryIndex.html" title="enum in org.apache.hadoop.hbase.regionserver.wal"><span class="typeNameLink">CompressionContext.DictionaryIndex</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.regionserver.wal.<a href="../../../../../../org/apache/hadoop/hbase/regionserver/wal/RingBufferTruck.Type.html" title="enum in org.apache.hadoop.hbase.regionserver.wal"><span class="typeNameLink">RingBufferTruck.Type</span></a></li>
 </ul>
 </li>
 </ul>
diff --git a/devapidocs/org/apache/hadoop/hbase/security/access/package-tree.html b/devapidocs/org/apache/hadoop/hbase/security/access/package-tree.html
index aed7a5a..099cf39 100644
--- a/devapidocs/org/apache/hadoop/hbase/security/access/package-tree.html
+++ b/devapidocs/org/apache/hadoop/hbase/security/access/package-tree.html
@@ -162,12 +162,12 @@
 <ul>
 <li type="circle">java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Enum.html?is-external=true" title="class or interface in java.lang"><span class="typeNameLink">Enum</span></a>&lt;E&gt; (implements java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Comparable.html?is-external=true" title="class or interface in java.lang">Comparable</a>&lt;T&gt;, java.io.<a href="https://docs.oracle.com/javase/8/docs/api/java/io/Serializable.html?is-external=true [...]
 <ul>
+<li type="circle">org.apache.hadoop.hbase.security.access.<a href="../../../../../../org/apache/hadoop/hbase/security/access/AccessController.OpType.html" title="enum in org.apache.hadoop.hbase.security.access"><span class="typeNameLink">AccessController.OpType</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.security.access.<a href="../../../../../../org/apache/hadoop/hbase/security/access/Permission.Scope.html" title="enum in org.apache.hadoop.hbase.security.access"><span class="typeNameLink">Permission.Scope</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.security.access.<a href="../../../../../../org/apache/hadoop/hbase/security/access/Permission.Action.html" title="enum in org.apache.hadoop.hbase.security.access"><span class="typeNameLink">Permission.Action</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.security.access.<a href="../../../../../../org/apache/hadoop/hbase/security/access/SnapshotScannerHDFSAclHelper.HDFSAclOperation.OperationType.html" title="enum in org.apache.hadoop.hbase.security.access"><span class="typeNameLink">SnapshotScannerHDFSAclHelper.HDFSAclOperation.OperationType</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.security.access.<a href="../../../../../../org/apache/hadoop/hbase/security/access/AccessControlFilter.Strategy.html" title="enum in org.apache.hadoop.hbase.security.access"><span class="typeNameLink">AccessControlFilter.Strategy</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.security.access.<a href="../../../../../../org/apache/hadoop/hbase/security/access/AccessController.OpType.html" title="enum in org.apache.hadoop.hbase.security.access"><span class="typeNameLink">AccessController.OpType</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.security.access.<a href="../../../../../../org/apache/hadoop/hbase/security/access/SnapshotScannerHDFSAclHelper.HDFSAclOperation.AclType.html" title="enum in org.apache.hadoop.hbase.security.access"><span class="typeNameLink">SnapshotScannerHDFSAclHelper.HDFSAclOperation.AclType</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.security.access.<a href="../../../../../../org/apache/hadoop/hbase/security/access/Permission.Action.html" title="enum in org.apache.hadoop.hbase.security.access"><span class="typeNameLink">Permission.Action</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.security.access.<a href="../../../../../../org/apache/hadoop/hbase/security/access/AccessControlFilter.Strategy.html" title="enum in org.apache.hadoop.hbase.security.access"><span class="typeNameLink">AccessControlFilter.Strategy</span></a></li>
 </ul>
 </li>
 </ul>
diff --git a/devapidocs/org/apache/hadoop/hbase/security/package-tree.html b/devapidocs/org/apache/hadoop/hbase/security/package-tree.html
index 0b85236..5c5c2f5 100644
--- a/devapidocs/org/apache/hadoop/hbase/security/package-tree.html
+++ b/devapidocs/org/apache/hadoop/hbase/security/package-tree.html
@@ -189,8 +189,8 @@
 <ul>
 <li type="circle">java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Enum.html?is-external=true" title="class or interface in java.lang"><span class="typeNameLink">Enum</span></a>&lt;E&gt; (implements java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Comparable.html?is-external=true" title="class or interface in java.lang">Comparable</a>&lt;T&gt;, java.io.<a href="https://docs.oracle.com/javase/8/docs/api/java/io/Serializable.html?is-external=true [...]
 <ul>
-<li type="circle">org.apache.hadoop.hbase.security.<a href="../../../../../org/apache/hadoop/hbase/security/SaslStatus.html" title="enum in org.apache.hadoop.hbase.security"><span class="typeNameLink">SaslStatus</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.security.<a href="../../../../../org/apache/hadoop/hbase/security/AuthMethod.html" title="enum in org.apache.hadoop.hbase.security"><span class="typeNameLink">AuthMethod</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.security.<a href="../../../../../org/apache/hadoop/hbase/security/SaslStatus.html" title="enum in org.apache.hadoop.hbase.security"><span class="typeNameLink">SaslStatus</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.security.<a href="../../../../../org/apache/hadoop/hbase/security/SaslUtil.QualityOfProtection.html" title="enum in org.apache.hadoop.hbase.security"><span class="typeNameLink">SaslUtil.QualityOfProtection</span></a></li>
 </ul>
 </li>
diff --git a/devapidocs/org/apache/hadoop/hbase/thrift/package-tree.html b/devapidocs/org/apache/hadoop/hbase/thrift/package-tree.html
index 50024bf..fba9877 100644
--- a/devapidocs/org/apache/hadoop/hbase/thrift/package-tree.html
+++ b/devapidocs/org/apache/hadoop/hbase/thrift/package-tree.html
@@ -212,8 +212,8 @@
 <li type="circle">java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Enum.html?is-external=true" title="class or interface in java.lang"><span class="typeNameLink">Enum</span></a>&lt;E&gt; (implements java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Comparable.html?is-external=true" title="class or interface in java.lang">Comparable</a>&lt;T&gt;, java.io.<a href="https://docs.oracle.com/javase/8/docs/api/java/io/Serializable.html?is-external=true [...]
 <ul>
 <li type="circle">org.apache.hadoop.hbase.thrift.<a href="../../../../../org/apache/hadoop/hbase/thrift/ThriftMetrics.ThriftServerType.html" title="enum in org.apache.hadoop.hbase.thrift"><span class="typeNameLink">ThriftMetrics.ThriftServerType</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.thrift.<a href="../../../../../org/apache/hadoop/hbase/thrift/MetricsThriftServerSourceFactoryImpl.FactoryStorage.html" title="enum in org.apache.hadoop.hbase.thrift"><span class="typeNameLink">MetricsThriftServerSourceFactoryImpl.FactoryStorage</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.thrift.<a href="../../../../../org/apache/hadoop/hbase/thrift/ImplType.html" title="enum in org.apache.hadoop.hbase.thrift"><span class="typeNameLink">ImplType</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.thrift.<a href="../../../../../org/apache/hadoop/hbase/thrift/MetricsThriftServerSourceFactoryImpl.FactoryStorage.html" title="enum in org.apache.hadoop.hbase.thrift"><span class="typeNameLink">MetricsThriftServerSourceFactoryImpl.FactoryStorage</span></a></li>
 </ul>
 </li>
 </ul>
diff --git a/devapidocs/org/apache/hadoop/hbase/util/package-tree.html b/devapidocs/org/apache/hadoop/hbase/util/package-tree.html
index ee6577b..3e58b72 100644
--- a/devapidocs/org/apache/hadoop/hbase/util/package-tree.html
+++ b/devapidocs/org/apache/hadoop/hbase/util/package-tree.html
@@ -532,15 +532,15 @@
 <ul>
 <li type="circle">java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Enum.html?is-external=true" title="class or interface in java.lang"><span class="typeNameLink">Enum</span></a>&lt;E&gt; (implements java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Comparable.html?is-external=true" title="class or interface in java.lang">Comparable</a>&lt;T&gt;, java.io.<a href="https://docs.oracle.com/javase/8/docs/api/java/io/Serializable.html?is-external=true [...]
 <ul>
-<li type="circle">org.apache.hadoop.hbase.util.<a href="../../../../../org/apache/hadoop/hbase/util/Order.html" title="enum in org.apache.hadoop.hbase.util"><span class="typeNameLink">Order</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.util.<a href="../../../../../org/apache/hadoop/hbase/util/Bytes.LexicographicalComparerHolder.UnsafeComparer.html" title="enum in org.apache.hadoop.hbase.util"><span class="typeNameLink">Bytes.LexicographicalComparerHolder.UnsafeComparer</span></a> (implements org.apache.hadoop.hbase.util.<a href="../../../../../org/apache/hadoop/hbase/util/Bytes.Comparer.html" title="interface in org.apache.hadoop.hbase.util">Bytes.Comparer</a>&lt;T&gt;)</li>
-<li type="circle">org.apache.hadoop.hbase.util.<a href="../../../../../org/apache/hadoop/hbase/util/IdReadWriteLockWithObjectPool.ReferenceType.html" title="enum in org.apache.hadoop.hbase.util"><span class="typeNameLink">IdReadWriteLockWithObjectPool.ReferenceType</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.util.<a href="../../../../../org/apache/hadoop/hbase/util/PrettyPrinter.Unit.html" title="enum in org.apache.hadoop.hbase.util"><span class="typeNameLink">PrettyPrinter.Unit</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.util.<a href="../../../../../org/apache/hadoop/hbase/util/HbckErrorReporter.ERROR_CODE.html" title="enum in org.apache.hadoop.hbase.util"><span class="typeNameLink">HbckErrorReporter.ERROR_CODE</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.util.<a href="../../../../../org/apache/hadoop/hbase/util/DNS.ServerType.html" title="enum in org.apache.hadoop.hbase.util"><span class="typeNameLink">DNS.ServerType</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.util.<a href="../../../../../org/apache/hadoop/hbase/util/IdReadWriteLockWithObjectPool.ReferenceType.html" title="enum in org.apache.hadoop.hbase.util"><span class="typeNameLink">IdReadWriteLockWithObjectPool.ReferenceType</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.util.<a href="../../../../../org/apache/hadoop/hbase/util/PoolMap.PoolType.html" title="enum in org.apache.hadoop.hbase.util"><span class="typeNameLink">PoolMap.PoolType</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.util.<a href="../../../../../org/apache/hadoop/hbase/util/Bytes.LexicographicalComparerHolder.PureJavaComparer.html" title="enum in org.apache.hadoop.hbase.util"><span class="typeNameLink">Bytes.LexicographicalComparerHolder.PureJavaComparer</span></a> (implements org.apache.hadoop.hbase.util.<a href="../../../../../org/apache/hadoop/hbase/util/Bytes.Comparer.html" title="interface in org.apache.hadoop.hbase.util">Bytes.Comparer</a>&lt;T&gt;)</li>
+<li type="circle">org.apache.hadoop.hbase.util.<a href="../../../../../org/apache/hadoop/hbase/util/DNS.ServerType.html" title="enum in org.apache.hadoop.hbase.util"><span class="typeNameLink">DNS.ServerType</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.util.<a href="../../../../../org/apache/hadoop/hbase/util/ChecksumType.html" title="enum in org.apache.hadoop.hbase.util"><span class="typeNameLink">ChecksumType</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.util.<a href="../../../../../org/apache/hadoop/hbase/util/PoolMap.PoolType.html" title="enum in org.apache.hadoop.hbase.util"><span class="typeNameLink">PoolMap.PoolType</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.util.<a href="../../../../../org/apache/hadoop/hbase/util/Order.html" title="enum in org.apache.hadoop.hbase.util"><span class="typeNameLink">Order</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.util.<a href="../../../../../org/apache/hadoop/hbase/util/Bytes.LexicographicalComparerHolder.UnsafeComparer.html" title="enum in org.apache.hadoop.hbase.util"><span class="typeNameLink">Bytes.LexicographicalComparerHolder.UnsafeComparer</span></a> (implements org.apache.hadoop.hbase.util.<a href="../../../../../org/apache/hadoop/hbase/util/Bytes.Comparer.html" title="interface in org.apache.hadoop.hbase.util">Bytes.Comparer</a>&lt;T&gt;)</li>
 </ul>
 </li>
 </ul>
diff --git a/devapidocs/src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.DefaultRackManager.html b/devapidocs/src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.DefaultRackManager.html
index 71d9218..d15cd10 100644
--- a/devapidocs/src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.DefaultRackManager.html
+++ b/devapidocs/src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.DefaultRackManager.html
@@ -34,859 +34,852 @@
 <span class="sourceLineNo">026</span>import java.util.HashMap;<a name="line.26"></a>
 <span class="sourceLineNo">027</span>import java.util.List;<a name="line.27"></a>
 <span class="sourceLineNo">028</span>import java.util.Map;<a name="line.28"></a>
-<span class="sourceLineNo">029</span>import org.apache.hadoop.hbase.HDFSBlocksDistribution;<a name="line.29"></a>
-<span class="sourceLineNo">030</span>import org.apache.hadoop.hbase.ServerName;<a name="line.30"></a>
-<span class="sourceLineNo">031</span>import org.apache.hadoop.hbase.client.RegionInfo;<a name="line.31"></a>
-<span class="sourceLineNo">032</span>import org.apache.hadoop.hbase.client.RegionReplicaUtil;<a name="line.32"></a>
-<span class="sourceLineNo">033</span>import org.apache.hadoop.hbase.master.RackManager;<a name="line.33"></a>
-<span class="sourceLineNo">034</span>import org.apache.hadoop.hbase.net.Address;<a name="line.34"></a>
-<span class="sourceLineNo">035</span>import org.apache.yetus.audience.InterfaceAudience;<a name="line.35"></a>
-<span class="sourceLineNo">036</span>import org.slf4j.Logger;<a name="line.36"></a>
-<span class="sourceLineNo">037</span>import org.slf4j.LoggerFactory;<a name="line.37"></a>
-<span class="sourceLineNo">038</span><a name="line.38"></a>
-<span class="sourceLineNo">039</span>/**<a name="line.39"></a>
-<span class="sourceLineNo">040</span> * An efficient array based implementation similar to ClusterState for keeping the status of the<a name="line.40"></a>
-<span class="sourceLineNo">041</span> * cluster in terms of region assignment and distribution. LoadBalancers, such as<a name="line.41"></a>
-<span class="sourceLineNo">042</span> * StochasticLoadBalancer uses this Cluster object because of hundreds of thousands of hashmap<a name="line.42"></a>
-<span class="sourceLineNo">043</span> * manipulations are very costly, which is why this class uses mostly indexes and arrays.<a name="line.43"></a>
-<span class="sourceLineNo">044</span> * &lt;p/&gt;<a name="line.44"></a>
-<span class="sourceLineNo">045</span> * BalancerClusterState tracks a list of unassigned regions, region assignments, and the server<a name="line.45"></a>
-<span class="sourceLineNo">046</span> * topology in terms of server names, hostnames and racks.<a name="line.46"></a>
-<span class="sourceLineNo">047</span> */<a name="line.47"></a>
-<span class="sourceLineNo">048</span>@InterfaceAudience.Private<a name="line.48"></a>
-<span class="sourceLineNo">049</span>class BalancerClusterState {<a name="line.49"></a>
-<span class="sourceLineNo">050</span><a name="line.50"></a>
-<span class="sourceLineNo">051</span>  private static final Logger LOG = LoggerFactory.getLogger(BalancerClusterState.class);<a name="line.51"></a>
+<span class="sourceLineNo">029</span>import org.agrona.collections.Hashing;<a name="line.29"></a>
+<span class="sourceLineNo">030</span>import org.agrona.collections.Int2IntCounterMap;<a name="line.30"></a>
+<span class="sourceLineNo">031</span>import org.apache.hadoop.hbase.HDFSBlocksDistribution;<a name="line.31"></a>
+<span class="sourceLineNo">032</span>import org.apache.hadoop.hbase.ServerName;<a name="line.32"></a>
+<span class="sourceLineNo">033</span>import org.apache.hadoop.hbase.client.RegionInfo;<a name="line.33"></a>
+<span class="sourceLineNo">034</span>import org.apache.hadoop.hbase.client.RegionReplicaUtil;<a name="line.34"></a>
+<span class="sourceLineNo">035</span>import org.apache.hadoop.hbase.master.RackManager;<a name="line.35"></a>
+<span class="sourceLineNo">036</span>import org.apache.hadoop.hbase.net.Address;<a name="line.36"></a>
+<span class="sourceLineNo">037</span>import org.apache.yetus.audience.InterfaceAudience;<a name="line.37"></a>
+<span class="sourceLineNo">038</span>import org.slf4j.Logger;<a name="line.38"></a>
+<span class="sourceLineNo">039</span>import org.slf4j.LoggerFactory;<a name="line.39"></a>
+<span class="sourceLineNo">040</span><a name="line.40"></a>
+<span class="sourceLineNo">041</span>/**<a name="line.41"></a>
+<span class="sourceLineNo">042</span> * An efficient array based implementation similar to ClusterState for keeping the status of the<a name="line.42"></a>
+<span class="sourceLineNo">043</span> * cluster in terms of region assignment and distribution. LoadBalancers, such as<a name="line.43"></a>
+<span class="sourceLineNo">044</span> * StochasticLoadBalancer uses this Cluster object because of hundreds of thousands of hashmap<a name="line.44"></a>
+<span class="sourceLineNo">045</span> * manipulations are very costly, which is why this class uses mostly indexes and arrays.<a name="line.45"></a>
+<span class="sourceLineNo">046</span> * &lt;p/&gt;<a name="line.46"></a>
+<span class="sourceLineNo">047</span> * BalancerClusterState tracks a list of unassigned regions, region assignments, and the server<a name="line.47"></a>
+<span class="sourceLineNo">048</span> * topology in terms of server names, hostnames and racks.<a name="line.48"></a>
+<span class="sourceLineNo">049</span> */<a name="line.49"></a>
+<span class="sourceLineNo">050</span>@InterfaceAudience.Private<a name="line.50"></a>
+<span class="sourceLineNo">051</span>class BalancerClusterState {<a name="line.51"></a>
 <span class="sourceLineNo">052</span><a name="line.52"></a>
-<span class="sourceLineNo">053</span>  ServerName[] servers;<a name="line.53"></a>
-<span class="sourceLineNo">054</span>  // ServerName uniquely identifies a region server. multiple RS can run on the same host<a name="line.54"></a>
-<span class="sourceLineNo">055</span>  String[] hosts;<a name="line.55"></a>
-<span class="sourceLineNo">056</span>  String[] racks;<a name="line.56"></a>
-<span class="sourceLineNo">057</span>  boolean multiServersPerHost = false; // whether or not any host has more than one server<a name="line.57"></a>
-<span class="sourceLineNo">058</span><a name="line.58"></a>
-<span class="sourceLineNo">059</span>  ArrayList&lt;String&gt; tables;<a name="line.59"></a>
-<span class="sourceLineNo">060</span>  RegionInfo[] regions;<a name="line.60"></a>
-<span class="sourceLineNo">061</span>  Deque&lt;BalancerRegionLoad&gt;[] regionLoads;<a name="line.61"></a>
-<span class="sourceLineNo">062</span>  private RegionHDFSBlockLocationFinder regionFinder;<a name="line.62"></a>
-<span class="sourceLineNo">063</span><a name="line.63"></a>
-<span class="sourceLineNo">064</span>  int[][] regionLocations; // regionIndex -&gt; list of serverIndex sorted by locality<a name="line.64"></a>
+<span class="sourceLineNo">053</span>  private static final Logger LOG = LoggerFactory.getLogger(BalancerClusterState.class);<a name="line.53"></a>
+<span class="sourceLineNo">054</span><a name="line.54"></a>
+<span class="sourceLineNo">055</span>  ServerName[] servers;<a name="line.55"></a>
+<span class="sourceLineNo">056</span>  // ServerName uniquely identifies a region server. multiple RS can run on the same host<a name="line.56"></a>
+<span class="sourceLineNo">057</span>  String[] hosts;<a name="line.57"></a>
+<span class="sourceLineNo">058</span>  String[] racks;<a name="line.58"></a>
+<span class="sourceLineNo">059</span>  boolean multiServersPerHost = false; // whether or not any host has more than one server<a name="line.59"></a>
+<span class="sourceLineNo">060</span><a name="line.60"></a>
+<span class="sourceLineNo">061</span>  ArrayList&lt;String&gt; tables;<a name="line.61"></a>
+<span class="sourceLineNo">062</span>  RegionInfo[] regions;<a name="line.62"></a>
+<span class="sourceLineNo">063</span>  Deque&lt;BalancerRegionLoad&gt;[] regionLoads;<a name="line.63"></a>
+<span class="sourceLineNo">064</span>  private RegionHDFSBlockLocationFinder regionFinder;<a name="line.64"></a>
 <span class="sourceLineNo">065</span><a name="line.65"></a>
-<span class="sourceLineNo">066</span>  int[] serverIndexToHostIndex; // serverIndex -&gt; host index<a name="line.66"></a>
-<span class="sourceLineNo">067</span>  int[] serverIndexToRackIndex; // serverIndex -&gt; rack index<a name="line.67"></a>
-<span class="sourceLineNo">068</span><a name="line.68"></a>
-<span class="sourceLineNo">069</span>  int[][] regionsPerServer; // serverIndex -&gt; region list<a name="line.69"></a>
-<span class="sourceLineNo">070</span>  int[] serverIndexToRegionsOffset; // serverIndex -&gt; offset of region list<a name="line.70"></a>
-<span class="sourceLineNo">071</span>  int[][] regionsPerHost; // hostIndex -&gt; list of regions<a name="line.71"></a>
-<span class="sourceLineNo">072</span>  int[][] regionsPerRack; // rackIndex -&gt; region list<a name="line.72"></a>
-<span class="sourceLineNo">073</span>  int[][] primariesOfRegionsPerServer; // serverIndex -&gt; sorted list of regions by primary region<a name="line.73"></a>
-<span class="sourceLineNo">074</span>                                       // index<a name="line.74"></a>
-<span class="sourceLineNo">075</span>  int[][] primariesOfRegionsPerHost; // hostIndex -&gt; sorted list of regions by primary region index<a name="line.75"></a>
-<span class="sourceLineNo">076</span>  int[][] primariesOfRegionsPerRack; // rackIndex -&gt; sorted list of regions by primary region index<a name="line.76"></a>
-<span class="sourceLineNo">077</span><a name="line.77"></a>
-<span class="sourceLineNo">078</span>  int[][] serversPerHost; // hostIndex -&gt; list of server indexes<a name="line.78"></a>
-<span class="sourceLineNo">079</span>  int[][] serversPerRack; // rackIndex -&gt; list of server indexes<a name="line.79"></a>
-<span class="sourceLineNo">080</span>  int[] regionIndexToServerIndex; // regionIndex -&gt; serverIndex<a name="line.80"></a>
-<span class="sourceLineNo">081</span>  int[] initialRegionIndexToServerIndex; // regionIndex -&gt; serverIndex (initial cluster state)<a name="line.81"></a>
-<span class="sourceLineNo">082</span>  int[] regionIndexToTableIndex; // regionIndex -&gt; tableIndex<a name="line.82"></a>
-<span class="sourceLineNo">083</span>  int[][] numRegionsPerServerPerTable; // serverIndex -&gt; tableIndex -&gt; # regions<a name="line.83"></a>
-<span class="sourceLineNo">084</span>  int[] numRegionsPerTable; // tableIndex -&gt; region count<a name="line.84"></a>
-<span class="sourceLineNo">085</span>  double[] meanRegionsPerTable; // mean region count per table<a name="line.85"></a>
-<span class="sourceLineNo">086</span>  double[] regionSkewByTable;       // skew on RS per by table<a name="line.86"></a>
-<span class="sourceLineNo">087</span>  double[] minRegionSkewByTable;       // min skew on RS per by table<a name="line.87"></a>
-<span class="sourceLineNo">088</span>  double[] maxRegionSkewByTable;       // max skew on RS per by table<a name="line.88"></a>
-<span class="sourceLineNo">089</span>  int[] regionIndexToPrimaryIndex; // regionIndex -&gt; regionIndex of the primary<a name="line.89"></a>
-<span class="sourceLineNo">090</span>  boolean hasRegionReplicas = false; // whether there is regions with replicas<a name="line.90"></a>
-<span class="sourceLineNo">091</span><a name="line.91"></a>
-<span class="sourceLineNo">092</span>  Integer[] serverIndicesSortedByRegionCount;<a name="line.92"></a>
-<span class="sourceLineNo">093</span>  Integer[] serverIndicesSortedByLocality;<a name="line.93"></a>
-<span class="sourceLineNo">094</span><a name="line.94"></a>
-<span class="sourceLineNo">095</span>  Map&lt;Address, Integer&gt; serversToIndex;<a name="line.95"></a>
-<span class="sourceLineNo">096</span>  Map&lt;String, Integer&gt; hostsToIndex;<a name="line.96"></a>
-<span class="sourceLineNo">097</span>  Map&lt;String, Integer&gt; racksToIndex;<a name="line.97"></a>
-<span class="sourceLineNo">098</span>  Map&lt;String, Integer&gt; tablesToIndex;<a name="line.98"></a>
-<span class="sourceLineNo">099</span>  Map&lt;RegionInfo, Integer&gt; regionsToIndex;<a name="line.99"></a>
-<span class="sourceLineNo">100</span>  float[] localityPerServer;<a name="line.100"></a>
-<span class="sourceLineNo">101</span><a name="line.101"></a>
-<span class="sourceLineNo">102</span>  int numServers;<a name="line.102"></a>
-<span class="sourceLineNo">103</span>  int numHosts;<a name="line.103"></a>
-<span class="sourceLineNo">104</span>  int numRacks;<a name="line.104"></a>
-<span class="sourceLineNo">105</span>  int numTables;<a name="line.105"></a>
-<span class="sourceLineNo">106</span>  int numRegions;<a name="line.106"></a>
-<span class="sourceLineNo">107</span><a name="line.107"></a>
-<span class="sourceLineNo">108</span>  int numMovedRegions = 0; // num moved regions from the initial configuration<a name="line.108"></a>
-<span class="sourceLineNo">109</span>  Map&lt;ServerName, List&lt;RegionInfo&gt;&gt; clusterState;<a name="line.109"></a>
-<span class="sourceLineNo">110</span><a name="line.110"></a>
-<span class="sourceLineNo">111</span>  private final RackManager rackManager;<a name="line.111"></a>
-<span class="sourceLineNo">112</span>  // Maps region -&gt; rackIndex -&gt; locality of region on rack<a name="line.112"></a>
-<span class="sourceLineNo">113</span>  private float[][] rackLocalities;<a name="line.113"></a>
-<span class="sourceLineNo">114</span>  // Maps localityType -&gt; region -&gt; [server|rack]Index with highest locality<a name="line.114"></a>
-<span class="sourceLineNo">115</span>  private int[][] regionsToMostLocalEntities;<a name="line.115"></a>
-<span class="sourceLineNo">116</span><a name="line.116"></a>
-<span class="sourceLineNo">117</span>  static class DefaultRackManager extends RackManager {<a name="line.117"></a>
-<span class="sourceLineNo">118</span>    @Override<a name="line.118"></a>
-<span class="sourceLineNo">119</span>    public String getRack(ServerName server) {<a name="line.119"></a>
-<span class="sourceLineNo">120</span>      return UNKNOWN_RACK;<a name="line.120"></a>
-<span class="sourceLineNo">121</span>    }<a name="line.121"></a>
-<span class="sourceLineNo">122</span>  }<a name="line.122"></a>
-<span class="sourceLineNo">123</span><a name="line.123"></a>
-<span class="sourceLineNo">124</span>  BalancerClusterState(Map&lt;ServerName, List&lt;RegionInfo&gt;&gt; clusterState,<a name="line.124"></a>
-<span class="sourceLineNo">125</span>    Map&lt;String, Deque&lt;BalancerRegionLoad&gt;&gt; loads, RegionHDFSBlockLocationFinder regionFinder,<a name="line.125"></a>
-<span class="sourceLineNo">126</span>    RackManager rackManager) {<a name="line.126"></a>
-<span class="sourceLineNo">127</span>    this(null, clusterState, loads, regionFinder, rackManager);<a name="line.127"></a>
-<span class="sourceLineNo">128</span>  }<a name="line.128"></a>
-<span class="sourceLineNo">129</span><a name="line.129"></a>
-<span class="sourceLineNo">130</span>  @SuppressWarnings("unchecked")<a name="line.130"></a>
-<span class="sourceLineNo">131</span>  BalancerClusterState(Collection&lt;RegionInfo&gt; unassignedRegions,<a name="line.131"></a>
-<span class="sourceLineNo">132</span>    Map&lt;ServerName, List&lt;RegionInfo&gt;&gt; clusterState, Map&lt;String, Deque&lt;BalancerRegionLoad&gt;&gt; loads,<a name="line.132"></a>
-<span class="sourceLineNo">133</span>    RegionHDFSBlockLocationFinder regionFinder, RackManager rackManager) {<a name="line.133"></a>
-<span class="sourceLineNo">134</span>    if (unassignedRegions == null) {<a name="line.134"></a>
-<span class="sourceLineNo">135</span>      unassignedRegions = Collections.emptyList();<a name="line.135"></a>
-<span class="sourceLineNo">136</span>    }<a name="line.136"></a>
-<span class="sourceLineNo">137</span><a name="line.137"></a>
-<span class="sourceLineNo">138</span>    serversToIndex = new HashMap&lt;&gt;();<a name="line.138"></a>
-<span class="sourceLineNo">139</span>    hostsToIndex = new HashMap&lt;&gt;();<a name="line.139"></a>
-<span class="sourceLineNo">140</span>    racksToIndex = new HashMap&lt;&gt;();<a name="line.140"></a>
-<span class="sourceLineNo">141</span>    tablesToIndex = new HashMap&lt;&gt;();<a name="line.141"></a>
-<span class="sourceLineNo">142</span><a name="line.142"></a>
-<span class="sourceLineNo">143</span>    // TODO: We should get the list of tables from master<a name="line.143"></a>
-<span class="sourceLineNo">144</span>    tables = new ArrayList&lt;&gt;();<a name="line.144"></a>
-<span class="sourceLineNo">145</span>    this.rackManager = rackManager != null ? rackManager : new DefaultRackManager();<a name="line.145"></a>
+<span class="sourceLineNo">066</span>  int[][] regionLocations; // regionIndex -&gt; list of serverIndex sorted by locality<a name="line.66"></a>
+<span class="sourceLineNo">067</span><a name="line.67"></a>
+<span class="sourceLineNo">068</span>  int[] serverIndexToHostIndex; // serverIndex -&gt; host index<a name="line.68"></a>
+<span class="sourceLineNo">069</span>  int[] serverIndexToRackIndex; // serverIndex -&gt; rack index<a name="line.69"></a>
+<span class="sourceLineNo">070</span><a name="line.70"></a>
+<span class="sourceLineNo">071</span>  int[][] regionsPerServer; // serverIndex -&gt; region list<a name="line.71"></a>
+<span class="sourceLineNo">072</span>  int[] serverIndexToRegionsOffset; // serverIndex -&gt; offset of region list<a name="line.72"></a>
+<span class="sourceLineNo">073</span>  int[][] regionsPerHost; // hostIndex -&gt; list of regions<a name="line.73"></a>
+<span class="sourceLineNo">074</span>  int[][] regionsPerRack; // rackIndex -&gt; region list<a name="line.74"></a>
+<span class="sourceLineNo">075</span>  Int2IntCounterMap[] colocatedReplicaCountsPerServer; // serverIndex -&gt; counts of colocated<a name="line.75"></a>
+<span class="sourceLineNo">076</span>                                       // replicas by primary region index<a name="line.76"></a>
+<span class="sourceLineNo">077</span>  Int2IntCounterMap[] colocatedReplicaCountsPerHost; // hostIndex -&gt; counts of colocated replicas by<a name="line.77"></a>
+<span class="sourceLineNo">078</span>                                      // primary region index<a name="line.78"></a>
+<span class="sourceLineNo">079</span>  Int2IntCounterMap[] colocatedReplicaCountsPerRack; // rackIndex -&gt; counts of colocated replicas by<a name="line.79"></a>
+<span class="sourceLineNo">080</span>                                      // primary region index<a name="line.80"></a>
+<span class="sourceLineNo">081</span><a name="line.81"></a>
+<span class="sourceLineNo">082</span>  int[][] serversPerHost; // hostIndex -&gt; list of server indexes<a name="line.82"></a>
+<span class="sourceLineNo">083</span>  int[][] serversPerRack; // rackIndex -&gt; list of server indexes<a name="line.83"></a>
+<span class="sourceLineNo">084</span>  int[] regionIndexToServerIndex; // regionIndex -&gt; serverIndex<a name="line.84"></a>
+<span class="sourceLineNo">085</span>  int[] initialRegionIndexToServerIndex; // regionIndex -&gt; serverIndex (initial cluster state)<a name="line.85"></a>
+<span class="sourceLineNo">086</span>  int[] regionIndexToTableIndex; // regionIndex -&gt; tableIndex<a name="line.86"></a>
+<span class="sourceLineNo">087</span>  int[][] numRegionsPerServerPerTable; // serverIndex -&gt; tableIndex -&gt; # regions<a name="line.87"></a>
+<span class="sourceLineNo">088</span>  int[] numRegionsPerTable; // tableIndex -&gt; region count<a name="line.88"></a>
+<span class="sourceLineNo">089</span>  double[] meanRegionsPerTable; // mean region count per table<a name="line.89"></a>
+<span class="sourceLineNo">090</span>  double[] regionSkewByTable;       // skew on RS per by table<a name="line.90"></a>
+<span class="sourceLineNo">091</span>  double[] minRegionSkewByTable;       // min skew on RS per by table<a name="line.91"></a>
+<span class="sourceLineNo">092</span>  double[] maxRegionSkewByTable;       // max skew on RS per by table<a name="line.92"></a>
+<span class="sourceLineNo">093</span>  int[] regionIndexToPrimaryIndex; // regionIndex -&gt; regionIndex of the primary<a name="line.93"></a>
+<span class="sourceLineNo">094</span>  boolean hasRegionReplicas = false; // whether there is regions with replicas<a name="line.94"></a>
+<span class="sourceLineNo">095</span><a name="line.95"></a>
+<span class="sourceLineNo">096</span>  Integer[] serverIndicesSortedByRegionCount;<a name="line.96"></a>
+<span class="sourceLineNo">097</span>  Integer[] serverIndicesSortedByLocality;<a name="line.97"></a>
+<span class="sourceLineNo">098</span><a name="line.98"></a>
+<span class="sourceLineNo">099</span>  Map&lt;Address, Integer&gt; serversToIndex;<a name="line.99"></a>
+<span class="sourceLineNo">100</span>  Map&lt;String, Integer&gt; hostsToIndex;<a name="line.100"></a>
+<span class="sourceLineNo">101</span>  Map&lt;String, Integer&gt; racksToIndex;<a name="line.101"></a>
+<span class="sourceLineNo">102</span>  Map&lt;String, Integer&gt; tablesToIndex;<a name="line.102"></a>
+<span class="sourceLineNo">103</span>  Map&lt;RegionInfo, Integer&gt; regionsToIndex;<a name="line.103"></a>
+<span class="sourceLineNo">104</span>  float[] localityPerServer;<a name="line.104"></a>
+<span class="sourceLineNo">105</span><a name="line.105"></a>
+<span class="sourceLineNo">106</span>  int numServers;<a name="line.106"></a>
+<span class="sourceLineNo">107</span>  int numHosts;<a name="line.107"></a>
+<span class="sourceLineNo">108</span>  int numRacks;<a name="line.108"></a>
+<span class="sourceLineNo">109</span>  int numTables;<a name="line.109"></a>
+<span class="sourceLineNo">110</span>  int numRegions;<a name="line.110"></a>
+<span class="sourceLineNo">111</span><a name="line.111"></a>
+<span class="sourceLineNo">112</span>  int numMovedRegions = 0; // num moved regions from the initial configuration<a name="line.112"></a>
+<span class="sourceLineNo">113</span>  Map&lt;ServerName, List&lt;RegionInfo&gt;&gt; clusterState;<a name="line.113"></a>
+<span class="sourceLineNo">114</span><a name="line.114"></a>
+<span class="sourceLineNo">115</span>  private final RackManager rackManager;<a name="line.115"></a>
+<span class="sourceLineNo">116</span>  // Maps region -&gt; rackIndex -&gt; locality of region on rack<a name="line.116"></a>
+<span class="sourceLineNo">117</span>  private float[][] rackLocalities;<a name="line.117"></a>
+<span class="sourceLineNo">118</span>  // Maps localityType -&gt; region -&gt; [server|rack]Index with highest locality<a name="line.118"></a>
+<span class="sourceLineNo">119</span>  private int[][] regionsToMostLocalEntities;<a name="line.119"></a>
+<span class="sourceLineNo">120</span><a name="line.120"></a>
+<span class="sourceLineNo">121</span>  static class DefaultRackManager extends RackManager {<a name="line.121"></a>
+<span class="sourceLineNo">122</span>    @Override<a name="line.122"></a>
+<span class="sourceLineNo">123</span>    public String getRack(ServerName server) {<a name="line.123"></a>
+<span class="sourceLineNo">124</span>      return UNKNOWN_RACK;<a name="line.124"></a>
+<span class="sourceLineNo">125</span>    }<a name="line.125"></a>
+<span class="sourceLineNo">126</span>  }<a name="line.126"></a>
+<span class="sourceLineNo">127</span><a name="line.127"></a>
+<span class="sourceLineNo">128</span>  BalancerClusterState(Map&lt;ServerName, List&lt;RegionInfo&gt;&gt; clusterState,<a name="line.128"></a>
+<span class="sourceLineNo">129</span>    Map&lt;String, Deque&lt;BalancerRegionLoad&gt;&gt; loads, RegionHDFSBlockLocationFinder regionFinder,<a name="line.129"></a>
+<span class="sourceLineNo">130</span>    RackManager rackManager) {<a name="line.130"></a>
+<span class="sourceLineNo">131</span>    this(null, clusterState, loads, regionFinder, rackManager);<a name="line.131"></a>
+<span class="sourceLineNo">132</span>  }<a name="line.132"></a>
+<span class="sourceLineNo">133</span><a name="line.133"></a>
+<span class="sourceLineNo">134</span>  @SuppressWarnings("unchecked")<a name="line.134"></a>
+<span class="sourceLineNo">135</span>  BalancerClusterState(Collection&lt;RegionInfo&gt; unassignedRegions,<a name="line.135"></a>
+<span class="sourceLineNo">136</span>    Map&lt;ServerName, List&lt;RegionInfo&gt;&gt; clusterState, Map&lt;String, Deque&lt;BalancerRegionLoad&gt;&gt; loads,<a name="line.136"></a>
+<span class="sourceLineNo">137</span>    RegionHDFSBlockLocationFinder regionFinder, RackManager rackManager) {<a name="line.137"></a>
+<span class="sourceLineNo">138</span>    if (unassignedRegions == null) {<a name="line.138"></a>
+<span class="sourceLineNo">139</span>      unassignedRegions = Collections.emptyList();<a name="line.139"></a>
+<span class="sourceLineNo">140</span>    }<a name="line.140"></a>
+<span class="sourceLineNo">141</span><a name="line.141"></a>
+<span class="sourceLineNo">142</span>    serversToIndex = new HashMap&lt;&gt;();<a name="line.142"></a>
+<span class="sourceLineNo">143</span>    hostsToIndex = new HashMap&lt;&gt;();<a name="line.143"></a>
+<span class="sourceLineNo">144</span>    racksToIndex = new HashMap&lt;&gt;();<a name="line.144"></a>
+<span class="sourceLineNo">145</span>    tablesToIndex = new HashMap&lt;&gt;();<a name="line.145"></a>
 <span class="sourceLineNo">146</span><a name="line.146"></a>
-<span class="sourceLineNo">147</span>    numRegions = 0;<a name="line.147"></a>
-<span class="sourceLineNo">148</span><a name="line.148"></a>
-<span class="sourceLineNo">149</span>    List&lt;List&lt;Integer&gt;&gt; serversPerHostList = new ArrayList&lt;&gt;();<a name="line.149"></a>
-<span class="sourceLineNo">150</span>    List&lt;List&lt;Integer&gt;&gt; serversPerRackList = new ArrayList&lt;&gt;();<a name="line.150"></a>
-<span class="sourceLineNo">151</span>    this.clusterState = clusterState;<a name="line.151"></a>
-<span class="sourceLineNo">152</span>    this.regionFinder = regionFinder;<a name="line.152"></a>
-<span class="sourceLineNo">153</span><a name="line.153"></a>
-<span class="sourceLineNo">154</span>    // Use servername and port as there can be dead servers in this list. We want everything with<a name="line.154"></a>
-<span class="sourceLineNo">155</span>    // a matching hostname and port to have the same index.<a name="line.155"></a>
-<span class="sourceLineNo">156</span>    for (ServerName sn : clusterState.keySet()) {<a name="line.156"></a>
-<span class="sourceLineNo">157</span>      if (sn == null) {<a name="line.157"></a>
-<span class="sourceLineNo">158</span>        LOG.warn("TODO: Enable TRACE on BaseLoadBalancer. Empty servername); " +<a name="line.158"></a>
-<span class="sourceLineNo">159</span>          "skipping; unassigned regions?");<a name="line.159"></a>
-<span class="sourceLineNo">160</span>        if (LOG.isTraceEnabled()) {<a name="line.160"></a>
-<span class="sourceLineNo">161</span>          LOG.trace("EMPTY SERVERNAME " + clusterState.toString());<a name="line.161"></a>
-<span class="sourceLineNo">162</span>        }<a name="line.162"></a>
-<span class="sourceLineNo">163</span>        continue;<a name="line.163"></a>
-<span class="sourceLineNo">164</span>      }<a name="line.164"></a>
-<span class="sourceLineNo">165</span>      if (serversToIndex.get(sn.getAddress()) == null) {<a name="line.165"></a>
-<span class="sourceLineNo">166</span>        serversToIndex.put(sn.getAddress(), numServers++);<a name="line.166"></a>
-<span class="sourceLineNo">167</span>      }<a name="line.167"></a>
-<span class="sourceLineNo">168</span>      if (!hostsToIndex.containsKey(sn.getHostname())) {<a name="line.168"></a>
-<span class="sourceLineNo">169</span>        hostsToIndex.put(sn.getHostname(), numHosts++);<a name="line.169"></a>
-<span class="sourceLineNo">170</span>        serversPerHostList.add(new ArrayList&lt;&gt;(1));<a name="line.170"></a>
+<span class="sourceLineNo">147</span>    // TODO: We should get the list of tables from master<a name="line.147"></a>
+<span class="sourceLineNo">148</span>    tables = new ArrayList&lt;&gt;();<a name="line.148"></a>
+<span class="sourceLineNo">149</span>    this.rackManager = rackManager != null ? rackManager : new DefaultRackManager();<a name="line.149"></a>
+<span class="sourceLineNo">150</span><a name="line.150"></a>
+<span class="sourceLineNo">151</span>    numRegions = 0;<a name="line.151"></a>
+<span class="sourceLineNo">152</span><a name="line.152"></a>
+<span class="sourceLineNo">153</span>    List&lt;List&lt;Integer&gt;&gt; serversPerHostList = new ArrayList&lt;&gt;();<a name="line.153"></a>
+<span class="sourceLineNo">154</span>    List&lt;List&lt;Integer&gt;&gt; serversPerRackList = new ArrayList&lt;&gt;();<a name="line.154"></a>
+<span class="sourceLineNo">155</span>    this.clusterState = clusterState;<a name="line.155"></a>
+<span class="sourceLineNo">156</span>    this.regionFinder = regionFinder;<a name="line.156"></a>
+<span class="sourceLineNo">157</span><a name="line.157"></a>
+<span class="sourceLineNo">158</span>    // Use servername and port as there can be dead servers in this list. We want everything with<a name="line.158"></a>
+<span class="sourceLineNo">159</span>    // a matching hostname and port to have the same index.<a name="line.159"></a>
+<span class="sourceLineNo">160</span>    for (ServerName sn : clusterState.keySet()) {<a name="line.160"></a>
+<span class="sourceLineNo">161</span>      if (sn == null) {<a name="line.161"></a>
+<span class="sourceLineNo">162</span>        LOG.warn("TODO: Enable TRACE on BaseLoadBalancer. Empty servername); " +<a name="line.162"></a>
+<span class="sourceLineNo">163</span>          "skipping; unassigned regions?");<a name="line.163"></a>
+<span class="sourceLineNo">164</span>        if (LOG.isTraceEnabled()) {<a name="line.164"></a>
+<span class="sourceLineNo">165</span>          LOG.trace("EMPTY SERVERNAME " + clusterState.toString());<a name="line.165"></a>
+<span class="sourceLineNo">166</span>        }<a name="line.166"></a>
+<span class="sourceLineNo">167</span>        continue;<a name="line.167"></a>
+<span class="sourceLineNo">168</span>      }<a name="line.168"></a>
+<span class="sourceLineNo">169</span>      if (serversToIndex.get(sn.getAddress()) == null) {<a name="line.169"></a>
+<span class="sourceLineNo">170</span>        serversToIndex.put(sn.getAddress(), numServers++);<a name="line.170"></a>
 <span class="sourceLineNo">171</span>      }<a name="line.171"></a>
-<span class="sourceLineNo">172</span><a name="line.172"></a>
-<span class="sourceLineNo">173</span>      int serverIndex = serversToIndex.get(sn.getAddress());<a name="line.173"></a>
-<span class="sourceLineNo">174</span>      int hostIndex = hostsToIndex.get(sn.getHostname());<a name="line.174"></a>
-<span class="sourceLineNo">175</span>      serversPerHostList.get(hostIndex).add(serverIndex);<a name="line.175"></a>
+<span class="sourceLineNo">172</span>      if (!hostsToIndex.containsKey(sn.getHostname())) {<a name="line.172"></a>
+<span class="sourceLineNo">173</span>        hostsToIndex.put(sn.getHostname(), numHosts++);<a name="line.173"></a>
+<span class="sourceLineNo">174</span>        serversPerHostList.add(new ArrayList&lt;&gt;(1));<a name="line.174"></a>
+<span class="sourceLineNo">175</span>      }<a name="line.175"></a>
 <span class="sourceLineNo">176</span><a name="line.176"></a>
-<span class="sourceLineNo">177</span>      String rack = this.rackManager.getRack(sn);<a name="line.177"></a>
-<span class="sourceLineNo">178</span>      if (!racksToIndex.containsKey(rack)) {<a name="line.178"></a>
-<span class="sourceLineNo">179</span>        racksToIndex.put(rack, numRacks++);<a name="line.179"></a>
-<span class="sourceLineNo">180</span>        serversPerRackList.add(new ArrayList&lt;&gt;());<a name="line.180"></a>
-<span class="sourceLineNo">181</span>      }<a name="line.181"></a>
-<span class="sourceLineNo">182</span>      int rackIndex = racksToIndex.get(rack);<a name="line.182"></a>
-<span class="sourceLineNo">183</span>      serversPerRackList.get(rackIndex).add(serverIndex);<a name="line.183"></a>
-<span class="sourceLineNo">184</span>    }<a name="line.184"></a>
-<span class="sourceLineNo">185</span><a name="line.185"></a>
-<span class="sourceLineNo">186</span>    // Count how many regions there are.<a name="line.186"></a>
-<span class="sourceLineNo">187</span>    for (Map.Entry&lt;ServerName, List&lt;RegionInfo&gt;&gt; entry : clusterState.entrySet()) {<a name="line.187"></a>
-<span class="sourceLineNo">188</span>      numRegions += entry.getValue().size();<a name="line.188"></a>
-<span class="sourceLineNo">189</span>    }<a name="line.189"></a>
-<span class="sourceLineNo">190</span>    numRegions += unassignedRegions.size();<a name="line.190"></a>
-<span class="sourceLineNo">191</span><a name="line.191"></a>
-<span class="sourceLineNo">192</span>    regionsToIndex = new HashMap&lt;&gt;(numRegions);<a name="line.192"></a>
-<span class="sourceLineNo">193</span>    servers = new ServerName[numServers];<a name="line.193"></a>
-<span class="sourceLineNo">194</span>    serversPerHost = new int[numHosts][];<a name="line.194"></a>
-<span class="sourceLineNo">195</span>    serversPerRack = new int[numRacks][];<a name="line.195"></a>
-<span class="sourceLineNo">196</span>    regions = new RegionInfo[numRegions];<a name="line.196"></a>
-<span class="sourceLineNo">197</span>    regionIndexToServerIndex = new int[numRegions];<a name="line.197"></a>
-<span class="sourceLineNo">198</span>    initialRegionIndexToServerIndex = new int[numRegions];<a name="line.198"></a>
-<span class="sourceLineNo">199</span>    regionIndexToTableIndex = new int[numRegions];<a name="line.199"></a>
-<span class="sourceLineNo">200</span>    regionIndexToPrimaryIndex = new int[numRegions];<a name="line.200"></a>
-<span class="sourceLineNo">201</span>    regionLoads = new Deque[numRegions];<a name="line.201"></a>
-<span class="sourceLineNo">202</span><a name="line.202"></a>
-<span class="sourceLineNo">203</span>    regionLocations = new int[numRegions][];<a name="line.203"></a>
-<span class="sourceLineNo">204</span>    serverIndicesSortedByRegionCount = new Integer[numServers];<a name="line.204"></a>
-<span class="sourceLineNo">205</span>    serverIndicesSortedByLocality = new Integer[numServers];<a name="line.205"></a>
-<span class="sourceLineNo">206</span>    localityPerServer = new float[numServers];<a name="line.206"></a>
-<span class="sourceLineNo">207</span><a name="line.207"></a>
-<span class="sourceLineNo">208</span>    serverIndexToHostIndex = new int[numServers];<a name="line.208"></a>
-<span class="sourceLineNo">209</span>    serverIndexToRackIndex = new int[numServers];<a name="line.209"></a>
-<span class="sourceLineNo">210</span>    regionsPerServer = new int[numServers][];<a name="line.210"></a>
-<span class="sourceLineNo">211</span>    serverIndexToRegionsOffset = new int[numServers];<a name="line.211"></a>
-<span class="sourceLineNo">212</span>    regionsPerHost = new int[numHosts][];<a name="line.212"></a>
-<span class="sourceLineNo">213</span>    regionsPerRack = new int[numRacks][];<a name="line.213"></a>
-<span class="sourceLineNo">214</span>    primariesOfRegionsPerServer = new int[numServers][];<a name="line.214"></a>
-<span class="sourceLineNo">215</span>    primariesOfRegionsPerHost = new int[numHosts][];<a name="line.215"></a>
-<span class="sourceLineNo">216</span>    primariesOfRegionsPerRack = new int[numRacks][];<a name="line.216"></a>
-<span class="sourceLineNo">217</span><a name="line.217"></a>
-<span class="sourceLineNo">218</span>    int tableIndex = 0, regionIndex = 0, regionPerServerIndex = 0;<a name="line.218"></a>
-<span class="sourceLineNo">219</span><a name="line.219"></a>
-<span class="sourceLineNo">220</span>    for (Map.Entry&lt;ServerName, List&lt;RegionInfo&gt;&gt; entry : clusterState.entrySet()) {<a name="line.220"></a>
-<span class="sourceLineNo">221</span>      if (entry.getKey() == null) {<a name="line.221"></a>
-<span class="sourceLineNo">222</span>        LOG.warn("SERVERNAME IS NULL, skipping " + entry.getValue());<a name="line.222"></a>
-<span class="sourceLineNo">223</span>        continue;<a name="line.223"></a>
-<span class="sourceLineNo">224</span>      }<a name="line.224"></a>
-<span class="sourceLineNo">225</span>      int serverIndex = serversToIndex.get(entry.getKey().getAddress());<a name="line.225"></a>
-<span class="sourceLineNo">226</span><a name="line.226"></a>
-<span class="sourceLineNo">227</span>      // keep the servername if this is the first server name for this hostname<a name="line.227"></a>
-<span class="sourceLineNo">228</span>      // or this servername has the newest startcode.<a name="line.228"></a>
-<span class="sourceLineNo">229</span>      if (servers[serverIndex] == null ||<a name="line.229"></a>
-<span class="sourceLineNo">230</span>        servers[serverIndex].getStartcode() &lt; entry.getKey().getStartcode()) {<a name="line.230"></a>
-<span class="sourceLineNo">231</span>        servers[serverIndex] = entry.getKey();<a name="line.231"></a>
-<span class="sourceLineNo">232</span>      }<a name="line.232"></a>
-<span class="sourceLineNo">233</span><a name="line.233"></a>
-<span class="sourceLineNo">234</span>      if (regionsPerServer[serverIndex] != null) {<a name="line.234"></a>
-<span class="sourceLineNo">235</span>        // there is another server with the same hostAndPort in ClusterState.<a name="line.235"></a>
-<span class="sourceLineNo">236</span>        // allocate the array for the total size<a name="line.236"></a>
-<span class="sourceLineNo">237</span>        regionsPerServer[serverIndex] =<a name="line.237"></a>
-<span class="sourceLineNo">238</span>          new int[entry.getValue().size() + regionsPerServer[serverIndex].length];<a name="line.238"></a>
-<span class="sourceLineNo">239</span>      } else {<a name="line.239"></a>
-<span class="sourceLineNo">240</span>        regionsPerServer[serverIndex] = new int[entry.getValue().size()];<a name="line.240"></a>
-<span class="sourceLineNo">241</span>      }<a name="line.241"></a>
-<span class="sourceLineNo">242</span>      primariesOfRegionsPerServer[serverIndex] = new int[regionsPerServer[serverIndex].length];<a name="line.242"></a>
-<span class="sourceLineNo">243</span>      serverIndicesSortedByRegionCount[serverIndex] = serverIndex;<a name="line.243"></a>
-<span class="sourceLineNo">244</span>      serverIndicesSortedByLocality[serverIndex] = serverIndex;<a name="line.244"></a>
-<span class="sourceLineNo">245</span>    }<a name="line.245"></a>
-<span class="sourceLineNo">246</span><a name="line.246"></a>
-<span class="sourceLineNo">247</span>    hosts = new String[numHosts];<a name="line.247"></a>
-<span class="sourceLineNo">248</span>    for (Map.Entry&lt;String, Integer&gt; entry : hostsToIndex.entrySet()) {<a name="line.248"></a>
-<span class="sourceLineNo">249</span>      hosts[entry.getValue()] = entry.getKey();<a name="line.249"></a>
+<span class="sourceLineNo">177</span>      int serverIndex = serversToIndex.get(sn.getAddress());<a name="line.177"></a>
+<span class="sourceLineNo">178</span>      int hostIndex = hostsToIndex.get(sn.getHostname());<a name="line.178"></a>
+<span class="sourceLineNo">179</span>      serversPerHostList.get(hostIndex).add(serverIndex);<a name="line.179"></a>
+<span class="sourceLineNo">180</span><a name="line.180"></a>
+<span class="sourceLineNo">181</span>      String rack = this.rackManager.getRack(sn);<a name="line.181"></a>
+<span class="sourceLineNo">182</span>      if (!racksToIndex.containsKey(rack)) {<a name="line.182"></a>
+<span class="sourceLineNo">183</span>        racksToIndex.put(rack, numRacks++);<a name="line.183"></a>
+<span class="sourceLineNo">184</span>        serversPerRackList.add(new ArrayList&lt;&gt;());<a name="line.184"></a>
+<span class="sourceLineNo">185</span>      }<a name="line.185"></a>
+<span class="sourceLineNo">186</span>      int rackIndex = racksToIndex.get(rack);<a name="line.186"></a>
+<span class="sourceLineNo">187</span>      serversPerRackList.get(rackIndex).add(serverIndex);<a name="line.187"></a>
+<span class="sourceLineNo">188</span>    }<a name="line.188"></a>
+<span class="sourceLineNo">189</span><a name="line.189"></a>
+<span class="sourceLineNo">190</span>    // Count how many regions there are.<a name="line.190"></a>
+<span class="sourceLineNo">191</span>    for (Map.Entry&lt;ServerName, List&lt;RegionInfo&gt;&gt; entry : clusterState.entrySet()) {<a name="line.191"></a>
+<span class="sourceLineNo">192</span>      numRegions += entry.getValue().size();<a name="line.192"></a>
+<span class="sourceLineNo">193</span>    }<a name="line.193"></a>
+<span class="sourceLineNo">194</span>    numRegions += unassignedRegions.size();<a name="line.194"></a>
+<span class="sourceLineNo">195</span><a name="line.195"></a>
+<span class="sourceLineNo">196</span>    regionsToIndex = new HashMap&lt;&gt;(numRegions);<a name="line.196"></a>
+<span class="sourceLineNo">197</span>    servers = new ServerName[numServers];<a name="line.197"></a>
+<span class="sourceLineNo">198</span>    serversPerHost = new int[numHosts][];<a name="line.198"></a>
+<span class="sourceLineNo">199</span>    serversPerRack = new int[numRacks][];<a name="line.199"></a>
+<span class="sourceLineNo">200</span>    regions = new RegionInfo[numRegions];<a name="line.200"></a>
+<span class="sourceLineNo">201</span>    regionIndexToServerIndex = new int[numRegions];<a name="line.201"></a>
+<span class="sourceLineNo">202</span>    initialRegionIndexToServerIndex = new int[numRegions];<a name="line.202"></a>
+<span class="sourceLineNo">203</span>    regionIndexToTableIndex = new int[numRegions];<a name="line.203"></a>
+<span class="sourceLineNo">204</span>    regionIndexToPrimaryIndex = new int[numRegions];<a name="line.204"></a>
+<span class="sourceLineNo">205</span>    regionLoads = new Deque[numRegions];<a name="line.205"></a>
+<span class="sourceLineNo">206</span><a name="line.206"></a>
+<span class="sourceLineNo">207</span>    regionLocations = new int[numRegions][];<a name="line.207"></a>
+<span class="sourceLineNo">208</span>    serverIndicesSortedByRegionCount = new Integer[numServers];<a name="line.208"></a>
+<span class="sourceLineNo">209</span>    serverIndicesSortedByLocality = new Integer[numServers];<a name="line.209"></a>
+<span class="sourceLineNo">210</span>    localityPerServer = new float[numServers];<a name="line.210"></a>
+<span class="sourceLineNo">211</span><a name="line.211"></a>
+<span class="sourceLineNo">212</span>    serverIndexToHostIndex = new int[numServers];<a name="line.212"></a>
+<span class="sourceLineNo">213</span>    serverIndexToRackIndex = new int[numServers];<a name="line.213"></a>
+<span class="sourceLineNo">214</span>    regionsPerServer = new int[numServers][];<a name="line.214"></a>
+<span class="sourceLineNo">215</span>    serverIndexToRegionsOffset = new int[numServers];<a name="line.215"></a>
+<span class="sourceLineNo">216</span>    regionsPerHost = new int[numHosts][];<a name="line.216"></a>
+<span class="sourceLineNo">217</span>    regionsPerRack = new int[numRacks][];<a name="line.217"></a>
+<span class="sourceLineNo">218</span>    colocatedReplicaCountsPerServer = new Int2IntCounterMap[numServers];<a name="line.218"></a>
+<span class="sourceLineNo">219</span>    colocatedReplicaCountsPerHost = new Int2IntCounterMap[numHosts];<a name="line.219"></a>
+<span class="sourceLineNo">220</span>    colocatedReplicaCountsPerRack = new Int2IntCounterMap[numRacks];<a name="line.220"></a>
+<span class="sourceLineNo">221</span><a name="line.221"></a>
+<span class="sourceLineNo">222</span>    int tableIndex = 0, regionIndex = 0, regionPerServerIndex = 0;<a name="line.222"></a>
+<span class="sourceLineNo">223</span><a name="line.223"></a>
+<span class="sourceLineNo">224</span>    for (Map.Entry&lt;ServerName, List&lt;RegionInfo&gt;&gt; entry : clusterState.entrySet()) {<a name="line.224"></a>
+<span class="sourceLineNo">225</span>      if (entry.getKey() == null) {<a name="line.225"></a>
+<span class="sourceLineNo">226</span>        LOG.warn("SERVERNAME IS NULL, skipping " + entry.getValue());<a name="line.226"></a>
+<span class="sourceLineNo">227</span>        continue;<a name="line.227"></a>
+<span class="sourceLineNo">228</span>      }<a name="line.228"></a>
+<span class="sourceLineNo">229</span>      int serverIndex = serversToIndex.get(entry.getKey().getAddress());<a name="line.229"></a>
+<span class="sourceLineNo">230</span><a name="line.230"></a>
+<span class="sourceLineNo">231</span>      // keep the servername if this is the first server name for this hostname<a name="line.231"></a>
+<span class="sourceLineNo">232</span>      // or this servername has the newest startcode.<a name="line.232"></a>
+<span class="sourceLineNo">233</span>      if (servers[serverIndex] == null ||<a name="line.233"></a>
+<span class="sourceLineNo">234</span>        servers[serverIndex].getStartcode() &lt; entry.getKey().getStartcode()) {<a name="line.234"></a>
+<span class="sourceLineNo">235</span>        servers[serverIndex] = entry.getKey();<a name="line.235"></a>
+<span class="sourceLineNo">236</span>      }<a name="line.236"></a>
+<span class="sourceLineNo">237</span><a name="line.237"></a>
+<span class="sourceLineNo">238</span>      if (regionsPerServer[serverIndex] != null) {<a name="line.238"></a>
+<span class="sourceLineNo">239</span>        // there is another server with the same hostAndPort in ClusterState.<a name="line.239"></a>
+<span class="sourceLineNo">240</span>        // allocate the array for the total size<a name="line.240"></a>
+<span class="sourceLineNo">241</span>        regionsPerServer[serverIndex] =<a name="line.241"></a>
+<span class="sourceLineNo">242</span>          new int[entry.getValue().size() + regionsPerServer[serverIndex].length];<a name="line.242"></a>
+<span class="sourceLineNo">243</span>      } else {<a name="line.243"></a>
+<span class="sourceLineNo">244</span>        regionsPerServer[serverIndex] = new int[entry.getValue().size()];<a name="line.244"></a>
+<span class="sourceLineNo">245</span>      }<a name="line.245"></a>
+<span class="sourceLineNo">246</span>      colocatedReplicaCountsPerServer[serverIndex] = new Int2IntCounterMap(<a name="line.246"></a>
+<span class="sourceLineNo">247</span>        regionsPerServer[serverIndex].length, Hashing.DEFAULT_LOAD_FACTOR, 0);<a name="line.247"></a>
+<span class="sourceLineNo">248</span>      serverIndicesSortedByRegionCount[serverIndex] = serverIndex;<a name="line.248"></a>
+<span class="sourceLineNo">249</span>      serverIndicesSortedByLocality[serverIndex] = serverIndex;<a name="line.249"></a>
 <span class="sourceLineNo">250</span>    }<a name="line.250"></a>
-<span class="sourceLineNo">251</span>    racks = new String[numRacks];<a name="line.251"></a>
-<span class="sourceLineNo">252</span>    for (Map.Entry&lt;String, Integer&gt; entry : racksToIndex.entrySet()) {<a name="line.252"></a>
-<span class="sourceLineNo">253</span>      racks[entry.getValue()] = entry.getKey();<a name="line.253"></a>
-<span class="sourceLineNo">254</span>    }<a name="line.254"></a>
-<span class="sourceLineNo">255</span><a name="line.255"></a>
-<span class="sourceLineNo">256</span>    for (Map.Entry&lt;ServerName, List&lt;RegionInfo&gt;&gt; entry : clusterState.entrySet()) {<a name="line.256"></a>
-<span class="sourceLineNo">257</span>      int serverIndex = serversToIndex.get(entry.getKey().getAddress());<a name="line.257"></a>
-<span class="sourceLineNo">258</span>      regionPerServerIndex = serverIndexToRegionsOffset[serverIndex];<a name="line.258"></a>
-<span class="sourceLineNo">259</span><a name="line.259"></a>
-<span class="sourceLineNo">260</span>      int hostIndex = hostsToIndex.get(entry.getKey().getHostname());<a name="line.260"></a>
-<span class="sourceLineNo">261</span>      serverIndexToHostIndex[serverIndex] = hostIndex;<a name="line.261"></a>
-<span class="sourceLineNo">262</span><a name="line.262"></a>
-<span class="sourceLineNo">263</span>      int rackIndex = racksToIndex.get(this.rackManager.getRack(entry.getKey()));<a name="line.263"></a>
-<span class="sourceLineNo">264</span>      serverIndexToRackIndex[serverIndex] = rackIndex;<a name="line.264"></a>
-<span class="sourceLineNo">265</span><a name="line.265"></a>
-<span class="sourceLineNo">266</span>      for (RegionInfo region : entry.getValue()) {<a name="line.266"></a>
-<span class="sourceLineNo">267</span>        registerRegion(region, regionIndex, serverIndex, loads, regionFinder);<a name="line.267"></a>
-<span class="sourceLineNo">268</span>        regionsPerServer[serverIndex][regionPerServerIndex++] = regionIndex;<a name="line.268"></a>
-<span class="sourceLineNo">269</span>        regionIndex++;<a name="line.269"></a>
-<span class="sourceLineNo">270</span>      }<a name="line.270"></a>
-<span class="sourceLineNo">271</span>      serverIndexToRegionsOffset[serverIndex] = regionPerServerIndex;<a name="line.271"></a>
-<span class="sourceLineNo">272</span>    }<a name="line.272"></a>
-<span class="sourceLineNo">273</span><a name="line.273"></a>
-<span class="sourceLineNo">274</span>    for (RegionInfo region : unassignedRegions) {<a name="line.274"></a>
-<span class="sourceLineNo">275</span>      registerRegion(region, regionIndex, -1, loads, regionFinder);<a name="line.275"></a>
-<span class="sourceLineNo">276</span>      regionIndex++;<a name="line.276"></a>
+<span class="sourceLineNo">251</span><a name="line.251"></a>
+<span class="sourceLineNo">252</span>    hosts = new String[numHosts];<a name="line.252"></a>
+<span class="sourceLineNo">253</span>    for (Map.Entry&lt;String, Integer&gt; entry : hostsToIndex.entrySet()) {<a name="line.253"></a>
+<span class="sourceLineNo">254</span>      hosts[entry.getValue()] = entry.getKey();<a name="line.254"></a>
+<span class="sourceLineNo">255</span>    }<a name="line.255"></a>
+<span class="sourceLineNo">256</span>    racks = new String[numRacks];<a name="line.256"></a>
+<span class="sourceLineNo">257</span>    for (Map.Entry&lt;String, Integer&gt; entry : racksToIndex.entrySet()) {<a name="line.257"></a>
+<span class="sourceLineNo">258</span>      racks[entry.getValue()] = entry.getKey();<a name="line.258"></a>
+<span class="sourceLineNo">259</span>    }<a name="line.259"></a>
+<span class="sourceLineNo">260</span><a name="line.260"></a>
+<span class="sourceLineNo">261</span>    for (Map.Entry&lt;ServerName, List&lt;RegionInfo&gt;&gt; entry : clusterState.entrySet()) {<a name="line.261"></a>
+<span class="sourceLineNo">262</span>      int serverIndex = serversToIndex.get(entry.getKey().getAddress());<a name="line.262"></a>
+<span class="sourceLineNo">263</span>      regionPerServerIndex = serverIndexToRegionsOffset[serverIndex];<a name="line.263"></a>
+<span class="sourceLineNo">264</span><a name="line.264"></a>
+<span class="sourceLineNo">265</span>      int hostIndex = hostsToIndex.get(entry.getKey().getHostname());<a name="line.265"></a>
+<span class="sourceLineNo">266</span>      serverIndexToHostIndex[serverIndex] = hostIndex;<a name="line.266"></a>
+<span class="sourceLineNo">267</span><a name="line.267"></a>
+<span class="sourceLineNo">268</span>      int rackIndex = racksToIndex.get(this.rackManager.getRack(entry.getKey()));<a name="line.268"></a>
+<span class="sourceLineNo">269</span>      serverIndexToRackIndex[serverIndex] = rackIndex;<a name="line.269"></a>
+<span class="sourceLineNo">270</span><a name="line.270"></a>
+<span class="sourceLineNo">271</span>      for (RegionInfo region : entry.getValue()) {<a name="line.271"></a>
+<span class="sourceLineNo">272</span>        registerRegion(region, regionIndex, serverIndex, loads, regionFinder);<a name="line.272"></a>
+<span class="sourceLineNo">273</span>        regionsPerServer[serverIndex][regionPerServerIndex++] = regionIndex;<a name="line.273"></a>
+<span class="sourceLineNo">274</span>        regionIndex++;<a name="line.274"></a>
+<span class="sourceLineNo">275</span>      }<a name="line.275"></a>
+<span class="sourceLineNo">276</span>      serverIndexToRegionsOffset[serverIndex] = regionPerServerIndex;<a name="line.276"></a>
 <span class="sourceLineNo">277</span>    }<a name="line.277"></a>
 <span class="sourceLineNo">278</span><a name="line.278"></a>
-<span class="sourceLineNo">279</span>    for (int i = 0; i &lt; serversPerHostList.size(); i++) {<a name="line.279"></a>
-<span class="sourceLineNo">280</span>      serversPerHost[i] = new int[serversPerHostList.get(i).size()];<a name="line.280"></a>
-<span class="sourceLineNo">281</span>      for (int j = 0; j &lt; serversPerHost[i].length; j++) {<a name="line.281"></a>
-<span class="sourceLineNo">282</span>        serversPerHost[i][j] = serversPerHostList.get(i).get(j);<a name="line.282"></a>
-<span class="sourceLineNo">283</span>      }<a name="line.283"></a>
-<span class="sourceLineNo">284</span>      if (serversPerHost[i].length &gt; 1) {<a name="line.284"></a>
-<span class="sourceLineNo">285</span>        multiServersPerHost = true;<a name="line.285"></a>
-<span class="sourceLineNo">286</span>      }<a name="line.286"></a>
-<span class="sourceLineNo">287</span>    }<a name="line.287"></a>
-<span class="sourceLineNo">288</span><a name="line.288"></a>
-<span class="sourceLineNo">289</span>    for (int i = 0; i &lt; serversPerRackList.size(); i++) {<a name="line.289"></a>
-<span class="sourceLineNo">290</span>      serversPerRack[i] = new int[serversPerRackList.get(i).size()];<a name="line.290"></a>
-<span class="sourceLineNo">291</span>      for (int j = 0; j &lt; serversPerRack[i].length; j++) {<a name="line.291"></a>
-<span class="sourceLineNo">292</span>        serversPerRack[i][j] = serversPerRackList.get(i).get(j);<a name="line.292"></a>
-<span class="sourceLineNo">293</span>      }<a name="line.293"></a>
-<span class="sourceLineNo">294</span>    }<a name="line.294"></a>
-<span class="sourceLineNo">295</span><a name="line.295"></a>
-<span class="sourceLineNo">296</span>    numTables = tables.size();<a name="line.296"></a>
-<span class="sourceLineNo">297</span>    LOG.debug("Number of tables={}", numTables);<a name="line.297"></a>
-<span class="sourceLineNo">298</span>    numRegionsPerServerPerTable = new int[numServers][numTables];<a name="line.298"></a>
-<span class="sourceLineNo">299</span>    numRegionsPerTable = new int[numTables];<a name="line.299"></a>
+<span class="sourceLineNo">279</span>    for (RegionInfo region : unassignedRegions) {<a name="line.279"></a>
+<span class="sourceLineNo">280</span>      registerRegion(region, regionIndex, -1, loads, regionFinder);<a name="line.280"></a>
+<span class="sourceLineNo">281</span>      regionIndex++;<a name="line.281"></a>
+<span class="sourceLineNo">282</span>    }<a name="line.282"></a>
+<span class="sourceLineNo">283</span><a name="line.283"></a>
+<span class="sourceLineNo">284</span>    for (int i = 0; i &lt; serversPerHostList.size(); i++) {<a name="line.284"></a>
+<span class="sourceLineNo">285</span>      serversPerHost[i] = new int[serversPerHostList.get(i).size()];<a name="line.285"></a>
+<span class="sourceLineNo">286</span>      for (int j = 0; j &lt; serversPerHost[i].length; j++) {<a name="line.286"></a>
+<span class="sourceLineNo">287</span>        serversPerHost[i][j] = serversPerHostList.get(i).get(j);<a name="line.287"></a>
+<span class="sourceLineNo">288</span>      }<a name="line.288"></a>
+<span class="sourceLineNo">289</span>      if (serversPerHost[i].length &gt; 1) {<a name="line.289"></a>
+<span class="sourceLineNo">290</span>        multiServersPerHost = true;<a name="line.290"></a>
+<span class="sourceLineNo">291</span>      }<a name="line.291"></a>
+<span class="sourceLineNo">292</span>    }<a name="line.292"></a>
+<span class="sourceLineNo">293</span><a name="line.293"></a>
+<span class="sourceLineNo">294</span>    for (int i = 0; i &lt; serversPerRackList.size(); i++) {<a name="line.294"></a>
+<span class="sourceLineNo">295</span>      serversPerRack[i] = new int[serversPerRackList.get(i).size()];<a name="line.295"></a>
+<span class="sourceLineNo">296</span>      for (int j = 0; j &lt; serversPerRack[i].length; j++) {<a name="line.296"></a>
+<span class="sourceLineNo">297</span>        serversPerRack[i][j] = serversPerRackList.get(i).get(j);<a name="line.297"></a>
+<span class="sourceLineNo">298</span>      }<a name="line.298"></a>
+<span class="sourceLineNo">299</span>    }<a name="line.299"></a>
 <span class="sourceLineNo">300</span><a name="line.300"></a>
-<span class="sourceLineNo">301</span>    for (int i = 0; i &lt; numServers; i++) {<a name="line.301"></a>
-<span class="sourceLineNo">302</span>      for (int j = 0; j &lt; numTables; j++) {<a name="line.302"></a>
-<span class="sourceLineNo">303</span>        numRegionsPerServerPerTable[i][j] = 0;<a name="line.303"></a>
-<span class="sourceLineNo">304</span>      }<a name="line.304"></a>
-<span class="sourceLineNo">305</span>    }<a name="line.305"></a>
-<span class="sourceLineNo">306</span><a name="line.306"></a>
-<span class="sourceLineNo">307</span>    for (int i = 0; i &lt; regionIndexToServerIndex.length; i++) {<a name="line.307"></a>
-<span class="sourceLineNo">308</span>      if (regionIndexToServerIndex[i] &gt;= 0) {<a name="line.308"></a>
-<span class="sourceLineNo">309</span>        numRegionsPerServerPerTable[regionIndexToServerIndex[i]][regionIndexToTableIndex[i]]++;<a name="line.309"></a>
-<span class="sourceLineNo">310</span>        numRegionsPerTable[regionIndexToTableIndex[i]]++;<a name="line.310"></a>
-<span class="sourceLineNo">311</span>      }<a name="line.311"></a>
-<span class="sourceLineNo">312</span>    }<a name="line.312"></a>
-<span class="sourceLineNo">313</span><a name="line.313"></a>
-<span class="sourceLineNo">314</span>    // Avoid repeated computation for planning<a name="line.314"></a>
-<span class="sourceLineNo">315</span>    meanRegionsPerTable = new double[numTables];<a name="line.315"></a>
-<span class="sourceLineNo">316</span>    regionSkewByTable = new double[numTables];<a name="line.316"></a>
-<span class="sourceLineNo">317</span>    maxRegionSkewByTable  = new double[numTables];<a name="line.317"></a>
-<span class="sourceLineNo">318</span>    minRegionSkewByTable = new double[numTables];<a name="line.318"></a>
-<span class="sourceLineNo">319</span><a name="line.319"></a>
-<span class="sourceLineNo">320</span>    for (int i = 0; i &lt; numTables; i++) {<a name="line.320"></a>
-<span class="sourceLineNo">321</span>      meanRegionsPerTable[i] = Double.valueOf(numRegionsPerTable[i]) / numServers;<a name="line.321"></a>
-<span class="sourceLineNo">322</span>      minRegionSkewByTable[i] += DoubleArrayCost.getMinSkew(numRegionsPerTable[i], numServers);<a name="line.322"></a>
-<span class="sourceLineNo">323</span>      maxRegionSkewByTable[i] += DoubleArrayCost.getMaxSkew(numRegionsPerTable[i], numServers);<a name="line.323"></a>
-<span class="sourceLineNo">324</span>    }<a name="line.324"></a>
-<span class="sourceLineNo">325</span><a name="line.325"></a>
-<span class="sourceLineNo">326</span>    for (int[] aNumRegionsPerServerPerTable : numRegionsPerServerPerTable) {<a name="line.326"></a>
-<span class="sourceLineNo">327</span>      for (int tableIdx = 0; tableIdx &lt; aNumRegionsPerServerPerTable.length; tableIdx++) {<a name="line.327"></a>
-<span class="sourceLineNo">328</span>        regionSkewByTable[tableIdx] += Math.abs(aNumRegionsPerServerPerTable[tableIdx] -<a name="line.328"></a>
-<span class="sourceLineNo">329</span>          meanRegionsPerTable[tableIdx]);<a name="line.329"></a>
-<span class="sourceLineNo">330</span>      }<a name="line.330"></a>
-<span class="sourceLineNo">331</span>    }<a name="line.331"></a>
-<span class="sourceLineNo">332</span><a name="line.332"></a>
-<span class="sourceLineNo">333</span>    for (int i = 0; i &lt; regions.length; i++) {<a name="line.333"></a>
-<span class="sourceLineNo">334</span>      RegionInfo info = regions[i];<a name="line.334"></a>
-<span class="sourceLineNo">335</span>      if (RegionReplicaUtil.isDefaultReplica(info)) {<a name="line.335"></a>
-<span class="sourceLineNo">336</span>        regionIndexToPrimaryIndex[i] = i;<a name="line.336"></a>
-<span class="sourceLineNo">337</span>      } else {<a name="line.337"></a>
-<span class="sourceLineNo">338</span>        hasRegionReplicas = true;<a name="line.338"></a>
-<span class="sourceLineNo">339</span>        RegionInfo primaryInfo = RegionReplicaUtil.getRegionInfoForDefaultReplica(info);<a name="line.339"></a>
-<span class="sourceLineNo">340</span>        regionIndexToPrimaryIndex[i] = regionsToIndex.getOrDefault(primaryInfo, -1);<a name="line.340"></a>
-<span class="sourceLineNo">341</span>      }<a name="line.341"></a>
-<span class="sourceLineNo">342</span>    }<a name="line.342"></a>
-<span class="sourceLineNo">343</span><a name="line.343"></a>
-<span class="sourceLineNo">344</span>    for (int i = 0; i &lt; regionsPerServer.length; i++) {<a name="line.344"></a>
-<span class="sourceLineNo">345</span>      primariesOfRegionsPerServer[i] = new int[regionsPerServer[i].length];<a name="line.345"></a>
-<span class="sourceLineNo">346</span>      for (int j = 0; j &lt; regionsPerServer[i].length; j++) {<a name="line.346"></a>
-<span class="sourceLineNo">347</span>        int primaryIndex = regionIndexToPrimaryIndex[regionsPerServer[i][j]];<a name="line.347"></a>
-<span class="sourceLineNo">348</span>        primariesOfRegionsPerServer[i][j] = primaryIndex;<a name="line.348"></a>
-<span class="sourceLineNo">349</span>      }<a name="line.349"></a>
-<span class="sourceLineNo">350</span>      // sort the regions by primaries.<a name="line.350"></a>
-<span class="sourceLineNo">351</span>      Arrays.sort(primariesOfRegionsPerServer[i]);<a name="line.351"></a>
-<span class="sourceLineNo">352</span>    }<a name="line.352"></a>
-<span class="sourceLineNo">353</span><a name="line.353"></a>
-<span class="sourceLineNo">354</span>    // compute regionsPerHost<a name="line.354"></a>
-<span class="sourceLineNo">355</span>    if (multiServersPerHost) {<a name="line.355"></a>
-<span class="sourceLineNo">356</span>      for (int i = 0; i &lt; serversPerHost.length; i++) {<a name="line.356"></a>
-<span class="sourceLineNo">357</span>        int numRegionsPerHost = 0;<a name="line.357"></a>
-<span class="sourceLineNo">358</span>        for (int j = 0; j &lt; serversPerHost[i].length; j++) {<a name="line.358"></a>
-<span class="sourceLineNo">359</span>          numRegionsPerHost += regionsPerServer[serversPerHost[i][j]].length;<a name="line.359"></a>
-<span class="sourceLineNo">360</span>        }<a name="line.360"></a>
-<span class="sourceLineNo">361</span>        regionsPerHost[i] = new int[numRegionsPerHost];<a name="line.361"></a>
-<span class="sourceLineNo">362</span>        primariesOfRegionsPerHost[i] = new int[numRegionsPerHost];<a name="line.362"></a>
-<span class="sourceLineNo">363</span>      }<a name="line.363"></a>
-<span class="sourceLineNo">364</span>      for (int i = 0; i &lt; serversPerHost.length; i++) {<a name="line.364"></a>
-<span class="sourceLineNo">365</span>        int numRegionPerHostIndex = 0;<a name="line.365"></a>
-<span class="sourceLineNo">366</span>        for (int j = 0; j &lt; serversPerHost[i].length; j++) {<a name="line.366"></a>
-<span class="sourceLineNo">367</span>          for (int k = 0; k &lt; regionsPerServer[serversPerHost[i][j]].length; k++) {<a name="line.367"></a>
-<span class="sourceLineNo">368</span>            int region = regionsPerServer[serversPerHost[i][j]][k];<a name="line.368"></a>
-<span class="sourceLineNo">369</span>            regionsPerHost[i][numRegionPerHostIndex] = region;<a name="line.369"></a>
-<span class="sourceLineNo">370</span>            int primaryIndex = regionIndexToPrimaryIndex[region];<a name="line.370"></a>
-<span class="sourceLineNo">371</span>            primariesOfRegionsPerHost[i][numRegionPerHostIndex] = primaryIndex;<a name="line.371"></a>
-<span class="sourceLineNo">372</span>            numRegionPerHostIndex++;<a name="line.372"></a>
-<span class="sourceLineNo">373</span>          }<a name="line.373"></a>
-<span class="sourceLineNo">374</span>        }<a name="line.374"></a>
-<span class="sourceLineNo">375</span>        // sort the regions by primaries.<a name="line.375"></a>
-<span class="sourceLineNo">376</span>        Arrays.sort(primariesOfRegionsPerHost[i]);<a name="line.376"></a>
+<span class="sourceLineNo">301</span>    numTables = tables.size();<a name="line.301"></a>
+<span class="sourceLineNo">302</span>    LOG.debug("Number of tables={}", numTables);<a name="line.302"></a>
+<span class="sourceLineNo">303</span>    numRegionsPerServerPerTable = new int[numServers][numTables];<a name="line.303"></a>
+<span class="sourceLineNo">304</span>    numRegionsPerTable = new int[numTables];<a name="line.304"></a>
+<span class="sourceLineNo">305</span><a name="line.305"></a>
+<span class="sourceLineNo">306</span>    for (int i = 0; i &lt; numServers; i++) {<a name="line.306"></a>
+<span class="sourceLineNo">307</span>      for (int j = 0; j &lt; numTables; j++) {<a name="line.307"></a>
+<span class="sourceLineNo">308</span>        numRegionsPerServerPerTable[i][j] = 0;<a name="line.308"></a>
+<span class="sourceLineNo">309</span>      }<a name="line.309"></a>
+<span class="sourceLineNo">310</span>    }<a name="line.310"></a>
+<span class="sourceLineNo">311</span><a name="line.311"></a>
+<span class="sourceLineNo">312</span>    for (int i = 0; i &lt; regionIndexToServerIndex.length; i++) {<a name="line.312"></a>
+<span class="sourceLineNo">313</span>      if (regionIndexToServerIndex[i] &gt;= 0) {<a name="line.313"></a>
+<span class="sourceLineNo">314</span>        numRegionsPerServerPerTable[regionIndexToServerIndex[i]][regionIndexToTableIndex[i]]++;<a name="line.314"></a>
+<span class="sourceLineNo">315</span>        numRegionsPerTable[regionIndexToTableIndex[i]]++;<a name="line.315"></a>
+<span class="sourceLineNo">316</span>      }<a name="line.316"></a>
+<span class="sourceLineNo">317</span>    }<a name="line.317"></a>
+<span class="sourceLineNo">318</span><a name="line.318"></a>
+<span class="sourceLineNo">319</span>    // Avoid repeated computation for planning<a name="line.319"></a>
+<span class="sourceLineNo">320</span>    meanRegionsPerTable = new double[numTables];<a name="line.320"></a>
+<span class="sourceLineNo">321</span>    regionSkewByTable = new double[numTables];<a name="line.321"></a>
+<span class="sourceLineNo">322</span>    maxRegionSkewByTable  = new double[numTables];<a name="line.322"></a>
+<span class="sourceLineNo">323</span>    minRegionSkewByTable = new double[numTables];<a name="line.323"></a>
+<span class="sourceLineNo">324</span><a name="line.324"></a>
+<span class="sourceLineNo">325</span>    for (int i = 0; i &lt; numTables; i++) {<a name="line.325"></a>
+<span class="sourceLineNo">326</span>      meanRegionsPerTable[i] = Double.valueOf(numRegionsPerTable[i]) / numServers;<a name="line.326"></a>
+<span class="sourceLineNo">327</span>      minRegionSkewByTable[i] += DoubleArrayCost.getMinSkew(numRegionsPerTable[i], numServers);<a name="line.327"></a>
+<span class="sourceLineNo">328</span>      maxRegionSkewByTable[i] += DoubleArrayCost.getMaxSkew(numRegionsPerTable[i], numServers);<a name="line.328"></a>
+<span class="sourceLineNo">329</span>    }<a name="line.329"></a>
+<span class="sourceLineNo">330</span><a name="line.330"></a>
+<span class="sourceLineNo">331</span>    for (int[] aNumRegionsPerServerPerTable : numRegionsPerServerPerTable) {<a name="line.331"></a>
+<span class="sourceLineNo">332</span>      for (int tableIdx = 0; tableIdx &lt; aNumRegionsPerServerPerTable.length; tableIdx++) {<a name="line.332"></a>
+<span class="sourceLineNo">333</span>        regionSkewByTable[tableIdx] += Math.abs(aNumRegionsPerServerPerTable[tableIdx] -<a name="line.333"></a>
+<span class="sourceLineNo">334</span>          meanRegionsPerTable[tableIdx]);<a name="line.334"></a>
+<span class="sourceLineNo">335</span>      }<a name="line.335"></a>
+<span class="sourceLineNo">336</span>    }<a name="line.336"></a>
+<span class="sourceLineNo">337</span><a name="line.337"></a>
+<span class="sourceLineNo">338</span>    for (int i = 0; i &lt; regions.length; i++) {<a name="line.338"></a>
+<span class="sourceLineNo">339</span>      RegionInfo info = regions[i];<a name="line.339"></a>
+<span class="sourceLineNo">340</span>      if (RegionReplicaUtil.isDefaultReplica(info)) {<a name="line.340"></a>
+<span class="sourceLineNo">341</span>        regionIndexToPrimaryIndex[i] = i;<a name="line.341"></a>
+<span class="sourceLineNo">342</span>      } else {<a name="line.342"></a>
+<span class="sourceLineNo">343</span>        hasRegionReplicas = true;<a name="line.343"></a>
+<span class="sourceLineNo">344</span>        RegionInfo primaryInfo = RegionReplicaUtil.getRegionInfoForDefaultReplica(info);<a name="line.344"></a>
+<span class="sourceLineNo">345</span>        regionIndexToPrimaryIndex[i] = regionsToIndex.getOrDefault(primaryInfo, -1);<a name="line.345"></a>
+<span class="sourceLineNo">346</span>      }<a name="line.346"></a>
+<span class="sourceLineNo">347</span>    }<a name="line.347"></a>
+<span class="sourceLineNo">348</span><a name="line.348"></a>
+<span class="sourceLineNo">349</span>    for (int i = 0; i &lt; regionsPerServer.length; i++) {<a name="line.349"></a>
+<span class="sourceLineNo">350</span>      colocatedReplicaCountsPerServer[i] = new Int2IntCounterMap(<a name="line.350"></a>
+<span class="sourceLineNo">351</span>        regionsPerServer[i].length, Hashing.DEFAULT_LOAD_FACTOR, 0);<a name="line.351"></a>
+<span class="sourceLineNo">352</span>      for (int j = 0; j &lt; regionsPerServer[i].length; j++) {<a name="line.352"></a>
+<span class="sourceLineNo">353</span>        int primaryIndex = regionIndexToPrimaryIndex[regionsPerServer[i][j]];<a name="line.353"></a>
+<span class="sourceLineNo">354</span>        colocatedReplicaCountsPerServer[i].getAndIncrement(primaryIndex);<a name="line.354"></a>
+<span class="sourceLineNo">355</span>      }<a name="line.355"></a>
+<span class="sourceLineNo">356</span>    }<a name="line.356"></a>
+<span class="sourceLineNo">357</span>    // compute regionsPerHost<a name="line.357"></a>
+<span class="sourceLineNo">358</span>    if (multiServersPerHost) {<a name="line.358"></a>
+<span class="sourceLineNo">359</span>      populateRegionPerLocationFromServer(regionsPerHost, colocatedReplicaCountsPerHost,<a name="line.359"></a>
+<span class="sourceLineNo">360</span>        serversPerHost);<a name="line.360"></a>
+<span class="sourceLineNo">361</span>    }<a name="line.361"></a>
+<span class="sourceLineNo">362</span><a name="line.362"></a>
+<span class="sourceLineNo">363</span>    // compute regionsPerRack<a name="line.363"></a>
+<span class="sourceLineNo">364</span>    if (numRacks &gt; 1) {<a name="line.364"></a>
+<span class="sourceLineNo">365</span>      populateRegionPerLocationFromServer(regionsPerRack, colocatedReplicaCountsPerRack,<a name="line.365"></a>
+<span class="sourceLineNo">366</span>        serversPerRack);<a name="line.366"></a>
+<span class="sourceLineNo">367</span>    }<a name="line.367"></a>
+<span class="sourceLineNo">368</span>  }<a name="line.368"></a>
+<span class="sourceLineNo">369</span><a name="line.369"></a>
+<span class="sourceLineNo">370</span>  private void populateRegionPerLocationFromServer(int[][] regionsPerLocation,<a name="line.370"></a>
+<span class="sourceLineNo">371</span>    Int2IntCounterMap[] colocatedReplicaCountsPerLocation,<a name="line.371"></a>
+<span class="sourceLineNo">372</span>    int[][] serversPerLocation) {<a name="line.372"></a>
+<span class="sourceLineNo">373</span>    for (int i = 0; i &lt; serversPerLocation.length; i++) {<a name="line.373"></a>
+<span class="sourceLineNo">374</span>      int numRegionsPerLocation = 0;<a name="line.374"></a>
+<span class="sourceLineNo">375</span>      for (int j = 0; j &lt; serversPerLocation[i].length; j++) {<a name="line.375"></a>
+<span class="sourceLineNo">376</span>        numRegionsPerLocation += regionsPerServer[serversPerLocation[i][j]].length;<a name="line.376"></a>
 <span class="sourceLineNo">377</span>      }<a name="line.377"></a>
-<span class="sourceLineNo">378</span>    }<a name="line.378"></a>
-<span class="sourceLineNo">379</span><a name="line.379"></a>
-<span class="sourceLineNo">380</span>    // compute regionsPerRack<a name="line.380"></a>
-<span class="sourceLineNo">381</span>    if (numRacks &gt; 1) {<a name="line.381"></a>
-<span class="sourceLineNo">382</span>      for (int i = 0; i &lt; serversPerRack.length; i++) {<a name="line.382"></a>
-<span class="sourceLineNo">383</span>        int numRegionsPerRack = 0;<a name="line.383"></a>
-<span class="sourceLineNo">384</span>        for (int j = 0; j &lt; serversPerRack[i].length; j++) {<a name="line.384"></a>
-<span class="sourceLineNo">385</span>          numRegionsPerRack += regionsPerServer[serversPerRack[i][j]].length;<a name="line.385"></a>
-<span class="sourceLineNo">386</span>        }<a name="line.386"></a>
-<span class="sourceLineNo">387</span>        regionsPerRack[i] = new int[numRegionsPerRack];<a name="line.387"></a>
-<span class="sourceLineNo">388</span>        primariesOfRegionsPerRack[i] = new int[numRegionsPerRack];<a name="line.388"></a>
-<span class="sourceLineNo">389</span>      }<a name="line.389"></a>
-<span class="sourceLineNo">390</span><a name="line.390"></a>
-<span class="sourceLineNo">391</span>      for (int i = 0; i &lt; serversPerRack.length; i++) {<a name="line.391"></a>
-<span class="sourceLineNo">392</span>        int numRegionPerRackIndex = 0;<a name="line.392"></a>
-<span class="sourceLineNo">393</span>        for (int j = 0; j &lt; serversPerRack[i].length; j++) {<a name="line.393"></a>
-<span class="sourceLineNo">394</span>          for (int k = 0; k &lt; regionsPerServer[serversPerRack[i][j]].length; k++) {<a name="line.394"></a>
-<span class="sourceLineNo">395</span>            int region = regionsPerServer[serversPerRack[i][j]][k];<a name="line.395"></a>
-<span class="sourceLineNo">396</span>            regionsPerRack[i][numRegionPerRackIndex] = region;<a name="line.396"></a>
-<span class="sourceLineNo">397</span>            int primaryIndex = regionIndexToPrimaryIndex[region];<a name="line.397"></a>
-<span class="sourceLineNo">398</span>            primariesOfRegionsPerRack[i][numRegionPerRackIndex] = primaryIndex;<a name="line.398"></a>
-<span class="sourceLineNo">399</span>            numRegionPerRackIndex++;<a name="line.399"></a>
-<span class="sourceLineNo">400</span>          }<a name="line.400"></a>
-<span class="sourceLineNo">401</span>        }<a name="line.401"></a>
-<span class="sourceLineNo">402</span>        // sort the regions by primaries.<a name="line.402"></a>
-<span class="sourceLineNo">403</span>        Arrays.sort(primariesOfRegionsPerRack[i]);<a name="line.403"></a>
-<span class="sourceLineNo">404</span>      }<a name="line.404"></a>
+<span class="sourceLineNo">378</span>      regionsPerLocation[i] = new int[numRegionsPerLocation];<a name="line.378"></a>
+<span class="sourceLineNo">379</span>      colocatedReplicaCountsPerLocation[i] = new Int2IntCounterMap(numRegionsPerLocation,<a name="line.379"></a>
+<span class="sourceLineNo">380</span>        Hashing.DEFAULT_LOAD_FACTOR, 0);<a name="line.380"></a>
+<span class="sourceLineNo">381</span>    }<a name="line.381"></a>
+<span class="sourceLineNo">382</span><a name="line.382"></a>
+<span class="sourceLineNo">383</span>    for (int i = 0; i &lt; serversPerLocation.length; i++) {<a name="line.383"></a>
+<span class="sourceLineNo">384</span>      int numRegionPerLocationIndex = 0;<a name="line.384"></a>
+<span class="sourceLineNo">385</span>      for (int j = 0; j &lt; serversPerLocation[i].length; j++) {<a name="line.385"></a>
+<span class="sourceLineNo">386</span>        for (int k = 0; k &lt; regionsPerServer[serversPerLocation[i][j]].length; k++) {<a name="line.386"></a>
+<span class="sourceLineNo">387</span>          int region = regionsPerServer[serversPerLocation[i][j]][k];<a name="line.387"></a>
+<span class="sourceLineNo">388</span>          regionsPerLocation[i][numRegionPerLocationIndex] = region;<a name="line.388"></a>
+<span class="sourceLineNo">389</span>          int primaryIndex = regionIndexToPrimaryIndex[region];<a name="line.389"></a>
+<span class="sourceLineNo">390</span>          colocatedReplicaCountsPerLocation[i].getAndIncrement(primaryIndex);<a name="line.390"></a>
+<span class="sourceLineNo">391</span>          numRegionPerLocationIndex++;<a name="line.391"></a>
+<span class="sourceLineNo">392</span>        }<a name="line.392"></a>
+<span class="sourceLineNo">393</span>      }<a name="line.393"></a>
+<span class="sourceLineNo">394</span>    }<a name="line.394"></a>
+<span class="sourceLineNo">395</span><a name="line.395"></a>
+<span class="sourceLineNo">396</span>  }<a name="line.396"></a>
+<span class="sourceLineNo">397</span><a name="line.397"></a>
+<span class="sourceLineNo">398</span>  /** Helper for Cluster constructor to handle a region */<a name="line.398"></a>
+<span class="sourceLineNo">399</span>  private void registerRegion(RegionInfo region, int regionIndex, int serverIndex,<a name="line.399"></a>
+<span class="sourceLineNo">400</span>    Map&lt;String, Deque&lt;BalancerRegionLoad&gt;&gt; loads, RegionHDFSBlockLocationFinder regionFinder) {<a name="line.400"></a>
+<span class="sourceLineNo">401</span>    String tableName = region.getTable().getNameAsString();<a name="line.401"></a>
+<span class="sourceLineNo">402</span>    if (!tablesToIndex.containsKey(tableName)) {<a name="line.402"></a>
+<span class="sourceLineNo">403</span>      tables.add(tableName);<a name="line.403"></a>
+<span class="sourceLineNo">404</span>      tablesToIndex.put(tableName, tablesToIndex.size());<a name="line.404"></a>
 <span class="sourceLineNo">405</span>    }<a name="line.405"></a>
-<span class="sourceLineNo">406</span>  }<a name="line.406"></a>
+<span class="sourceLineNo">406</span>    int tableIndex = tablesToIndex.get(tableName);<a name="line.406"></a>
 <span class="sourceLineNo">407</span><a name="line.407"></a>
-<span class="sourceLineNo">408</span>  /** Helper for Cluster constructor to handle a region */<a name="line.408"></a>
-<span class="sourceLineNo">409</span>  private void registerRegion(RegionInfo region, int regionIndex, int serverIndex,<a name="line.409"></a>
-<span class="sourceLineNo">410</span>    Map&lt;String, Deque&lt;BalancerRegionLoad&gt;&gt; loads, RegionHDFSBlockLocationFinder regionFinder) {<a name="line.410"></a>
-<span class="sourceLineNo">411</span>    String tableName = region.getTable().getNameAsString();<a name="line.411"></a>
-<span class="sourceLineNo">412</span>    if (!tablesToIndex.containsKey(tableName)) {<a name="line.412"></a>
-<span class="sourceLineNo">413</span>      tables.add(tableName);<a name="line.413"></a>
-<span class="sourceLineNo">414</span>      tablesToIndex.put(tableName, tablesToIndex.size());<a name="line.414"></a>
-<span class="sourceLineNo">415</span>    }<a name="line.415"></a>
-<span class="sourceLineNo">416</span>    int tableIndex = tablesToIndex.get(tableName);<a name="line.416"></a>
-<span class="sourceLineNo">417</span><a name="line.417"></a>
-<span class="sourceLineNo">418</span>    regionsToIndex.put(region, regionIndex);<a name="line.418"></a>
-<span class="sourceLineNo">419</span>    regions[regionIndex] = region;<a name="line.419"></a>
-<span class="sourceLineNo">420</span>    regionIndexToServerIndex[regionIndex] = serverIndex;<a name="line.420"></a>
-<span class="sourceLineNo">421</span>    initialRegionIndexToServerIndex[regionIndex] = serverIndex;<a name="line.421"></a>
-<span class="sourceLineNo">422</span>    regionIndexToTableIndex[regionIndex] = tableIndex;<a name="line.422"></a>
-<span class="sourceLineNo">423</span><a name="line.423"></a>
-<span class="sourceLineNo">424</span>    // region load<a name="line.424"></a>
-<span class="sourceLineNo">425</span>    if (loads != null) {<a name="line.425"></a>
-<span class="sourceLineNo">426</span>      Deque&lt;BalancerRegionLoad&gt; rl = loads.get(region.getRegionNameAsString());<a name="line.426"></a>
-<span class="sourceLineNo">427</span>      // That could have failed if the RegionLoad is using the other regionName<a name="line.427"></a>
-<span class="sourceLineNo">428</span>      if (rl == null) {<a name="line.428"></a>
-<span class="sourceLineNo">429</span>        // Try getting the region load using encoded name.<a name="line.429"></a>
-<span class="sourceLineNo">430</span>        rl = loads.get(region.getEncodedName());<a name="line.430"></a>
-<span class="sourceLineNo">431</span>      }<a name="line.431"></a>
-<span class="sourceLineNo">432</span>      regionLoads[regionIndex] = rl;<a name="line.432"></a>
-<span class="sourceLineNo">433</span>    }<a name="line.433"></a>
-<span class="sourceLineNo">434</span><a name="line.434"></a>
-<span class="sourceLineNo">435</span>    if (regionFinder != null) {<a name="line.435"></a>
-<span class="sourceLineNo">436</span>      // region location<a name="line.436"></a>
-<span class="sourceLineNo">437</span>      List&lt;ServerName&gt; loc = regionFinder.getTopBlockLocations(region);<a name="line.437"></a>
-<span class="sourceLineNo">438</span>      regionLocations[regionIndex] = new int[loc.size()];<a name="line.438"></a>
-<span class="sourceLineNo">439</span>      for (int i = 0; i &lt; loc.size(); i++) {<a name="line.439"></a>
-<span class="sourceLineNo">440</span>        regionLocations[regionIndex][i] = loc.get(i) == null ? -1 :<a name="line.440"></a>
-<span class="sourceLineNo">441</span>          (serversToIndex.get(loc.get(i).getAddress()) == null ? -1 :<a name="line.441"></a>
-<span class="sourceLineNo">442</span>            serversToIndex.get(loc.get(i).getAddress()));<a name="line.442"></a>
-<span class="sourceLineNo">443</span>      }<a name="line.443"></a>
-<span class="sourceLineNo">444</span>    }<a name="line.444"></a>
-<span class="sourceLineNo">445</span>  }<a name="line.445"></a>
-<span class="sourceLineNo">446</span><a name="line.446"></a>
-<span class="sourceLineNo">447</span>  /**<a name="line.447"></a>
-<span class="sourceLineNo">448</span>   * Returns true iff a given server has less regions than the balanced amount<a name="line.448"></a>
+<span class="sourceLineNo">408</span>    regionsToIndex.put(region, regionIndex);<a name="line.408"></a>
+<span class="sourceLineNo">409</span>    regions[regionIndex] = region;<a name="line.409"></a>
+<span class="sourceLineNo">410</span>    regionIndexToServerIndex[regionIndex] = serverIndex;<a name="line.410"></a>
+<span class="sourceLineNo">411</span>    initialRegionIndexToServerIndex[regionIndex] = serverIndex;<a name="line.411"></a>
+<span class="sourceLineNo">412</span>    regionIndexToTableIndex[regionIndex] = tableIndex;<a name="line.412"></a>
+<span class="sourceLineNo">413</span><a name="line.413"></a>
+<span class="sourceLineNo">414</span>    // region load<a name="line.414"></a>
+<span class="sourceLineNo">415</span>    if (loads != null) {<a name="line.415"></a>
+<span class="sourceLineNo">416</span>      Deque&lt;BalancerRegionLoad&gt; rl = loads.get(region.getRegionNameAsString());<a name="line.416"></a>
+<span class="sourceLineNo">417</span>      // That could have failed if the RegionLoad is using the other regionName<a name="line.417"></a>
+<span class="sourceLineNo">418</span>      if (rl == null) {<a name="line.418"></a>
+<span class="sourceLineNo">419</span>        // Try getting the region load using encoded name.<a name="line.419"></a>
+<span class="sourceLineNo">420</span>        rl = loads.get(region.getEncodedName());<a name="line.420"></a>
+<span class="sourceLineNo">421</span>      }<a name="line.421"></a>
+<span class="sourceLineNo">422</span>      regionLoads[regionIndex] = rl;<a name="line.422"></a>
+<span class="sourceLineNo">423</span>    }<a name="line.423"></a>
+<span class="sourceLineNo">424</span><a name="line.424"></a>
+<span class="sourceLineNo">425</span>    if (regionFinder != null) {<a name="line.425"></a>
+<span class="sourceLineNo">426</span>      // region location<a name="line.426"></a>
+<span class="sourceLineNo">427</span>      List&lt;ServerName&gt; loc = regionFinder.getTopBlockLocations(region);<a name="line.427"></a>
+<span class="sourceLineNo">428</span>      regionLocations[regionIndex] = new int[loc.size()];<a name="line.428"></a>
+<span class="sourceLineNo">429</span>      for (int i = 0; i &lt; loc.size(); i++) {<a name="line.429"></a>
+<span class="sourceLineNo">430</span>        regionLocations[regionIndex][i] = loc.get(i) == null ? -1 :<a name="line.430"></a>
+<span class="sourceLineNo">431</span>          (serversToIndex.get(loc.get(i).getAddress()) == null ? -1 :<a name="line.431"></a>
+<span class="sourceLineNo">432</span>            serversToIndex.get(loc.get(i).getAddress()));<a name="line.432"></a>
+<span class="sourceLineNo">433</span>      }<a name="line.433"></a>
+<span class="sourceLineNo">434</span>    }<a name="line.434"></a>
+<span class="sourceLineNo">435</span>  }<a name="line.435"></a>
+<span class="sourceLineNo">436</span><a name="line.436"></a>
+<span class="sourceLineNo">437</span>  /**<a name="line.437"></a>
+<span class="sourceLineNo">438</span>   * Returns true iff a given server has less regions than the balanced amount<a name="line.438"></a>
+<span class="sourceLineNo">439</span>   */<a name="line.439"></a>
+<span class="sourceLineNo">440</span>  public boolean serverHasTooFewRegions(int server) {<a name="line.440"></a>
+<span class="sourceLineNo">441</span>    int minLoad = this.numRegions / numServers;<a name="line.441"></a>
+<span class="sourceLineNo">442</span>    int numRegions = getNumRegions(server);<a name="line.442"></a>
+<span class="sourceLineNo">443</span>    return numRegions &lt; minLoad;<a name="line.443"></a>
+<span class="sourceLineNo">444</span>  }<a name="line.444"></a>
+<span class="sourceLineNo">445</span><a name="line.445"></a>
+<span class="sourceLineNo">446</span>  /**<a name="line.446"></a>
+<span class="sourceLineNo">447</span>   * Retrieves and lazily initializes a field storing the locality of every region/server<a name="line.447"></a>
+<span class="sourceLineNo">448</span>   * combination<a name="line.448"></a>
 <span class="sourceLineNo">449</span>   */<a name="line.449"></a>
-<span class="sourceLineNo">450</span>  public boolean serverHasTooFewRegions(int server) {<a name="line.450"></a>
-<span class="sourceLineNo">451</span>    int minLoad = this.numRegions / numServers;<a name="line.451"></a>
-<span class="sourceLineNo">452</span>    int numRegions = getNumRegions(server);<a name="line.452"></a>
-<span class="sourceLineNo">453</span>    return numRegions &lt; minLoad;<a name="line.453"></a>
-<span class="sourceLineNo">454</span>  }<a name="line.454"></a>
-<span class="sourceLineNo">455</span><a name="line.455"></a>
-<span class="sourceLineNo">456</span>  /**<a name="line.456"></a>
-<span class="sourceLineNo">457</span>   * Retrieves and lazily initializes a field storing the locality of every region/server<a name="line.457"></a>
-<span class="sourceLineNo">458</span>   * combination<a name="line.458"></a>
-<span class="sourceLineNo">459</span>   */<a name="line.459"></a>
-<span class="sourceLineNo">460</span>  public float[][] getOrComputeRackLocalities() {<a name="line.460"></a>
-<span class="sourceLineNo">461</span>    if (rackLocalities == null || regionsToMostLocalEntities == null) {<a name="line.461"></a>
-<span class="sourceLineNo">462</span>      computeCachedLocalities();<a name="line.462"></a>
-<span class="sourceLineNo">463</span>    }<a name="line.463"></a>
-<span class="sourceLineNo">464</span>    return rackLocalities;<a name="line.464"></a>
-<span class="sourceLineNo">465</span>  }<a name="line.465"></a>
-<span class="sourceLineNo">466</span><a name="line.466"></a>
-<span class="sourceLineNo">467</span>  /**<a name="line.467"></a>
-<span class="sourceLineNo">468</span>   * Lazily initializes and retrieves a mapping of region -&gt; server for which region has the highest<a name="line.468"></a>
-<span class="sourceLineNo">469</span>   * the locality<a name="line.469"></a>
+<span class="sourceLineNo">450</span>  public float[][] getOrComputeRackLocalities() {<a name="line.450"></a>
+<span class="sourceLineNo">451</span>    if (rackLocalities == null || regionsToMostLocalEntities == null) {<a name="line.451"></a>
+<span class="sourceLineNo">452</span>      computeCachedLocalities();<a name="line.452"></a>
+<span class="sourceLineNo">453</span>    }<a name="line.453"></a>
+<span class="sourceLineNo">454</span>    return rackLocalities;<a name="line.454"></a>
+<span class="sourceLineNo">455</span>  }<a name="line.455"></a>
+<span class="sourceLineNo">456</span><a name="line.456"></a>
+<span class="sourceLineNo">457</span>  /**<a name="line.457"></a>
+<span class="sourceLineNo">458</span>   * Lazily initializes and retrieves a mapping of region -&gt; server for which region has the highest<a name="line.458"></a>
+<span class="sourceLineNo">459</span>   * the locality<a name="line.459"></a>
+<span class="sourceLineNo">460</span>   */<a name="line.460"></a>
+<span class="sourceLineNo">461</span>  public int[] getOrComputeRegionsToMostLocalEntities(BalancerClusterState.LocalityType type) {<a name="line.461"></a>
+<span class="sourceLineNo">462</span>    if (rackLocalities == null || regionsToMostLocalEntities == null) {<a name="line.462"></a>
+<span class="sourceLineNo">463</span>      computeCachedLocalities();<a name="line.463"></a>
+<span class="sourceLineNo">464</span>    }<a name="line.464"></a>
+<span class="sourceLineNo">465</span>    return regionsToMostLocalEntities[type.ordinal()];<a name="line.465"></a>
+<span class="sourceLineNo">466</span>  }<a name="line.466"></a>
+<span class="sourceLineNo">467</span><a name="line.467"></a>
+<span class="sourceLineNo">468</span>  /**<a name="line.468"></a>
+<span class="sourceLineNo">469</span>   * Looks up locality from cache of localities. Will create cache if it does not already exist.<a name="line.469"></a>
 <span class="sourceLineNo">470</span>   */<a name="line.470"></a>
-<span class="sourceLineNo">471</span>  public int[] getOrComputeRegionsToMostLocalEntities(BalancerClusterState.LocalityType type) {<a name="line.471"></a>
-<span class="sourceLineNo">472</span>    if (rackLocalities == null || regionsToMostLocalEntities == null) {<a name="line.472"></a>
-<span class="sourceLineNo">473</span>      computeCachedLocalities();<a name="line.473"></a>
-<span class="sourceLineNo">474</span>    }<a name="line.474"></a>
-<span class="sourceLineNo">475</span>    return regionsToMostLocalEntities[type.ordinal()];<a name="line.475"></a>
-<span class="sourceLineNo">476</span>  }<a name="line.476"></a>
-<span class="sourceLineNo">477</span><a name="line.477"></a>
-<span class="sourceLineNo">478</span>  /**<a name="line.478"></a>
-<span class="sourceLineNo">479</span>   * Looks up locality from cache of localities. Will create cache if it does not already exist.<a name="line.479"></a>
-<span class="sourceLineNo">480</span>   */<a name="line.480"></a>
-<span class="sourceLineNo">481</span>  public float getOrComputeLocality(int region, int entity,<a name="line.481"></a>
-<span class="sourceLineNo">482</span>    BalancerClusterState.LocalityType type) {<a name="line.482"></a>
-<span class="sourceLineNo">483</span>    switch (type) {<a name="line.483"></a>
-<span class="sourceLineNo">484</span>      case SERVER:<a name="line.484"></a>
-<span class="sourceLineNo">485</span>        return getLocalityOfRegion(region, entity);<a name="line.485"></a>
-<span class="sourceLineNo">486</span>      case RACK:<a name="line.486"></a>
-<span class="sourceLineNo">487</span>        return getOrComputeRackLocalities()[region][entity];<a name="line.487"></a>
-<span class="sourceLineNo">488</span>      default:<a name="line.488"></a>
-<span class="sourceLineNo">489</span>        throw new IllegalArgumentException("Unsupported LocalityType: " + type);<a name="line.489"></a>
-<span class="sourceLineNo">490</span>    }<a name="line.490"></a>
-<span class="sourceLineNo">491</span>  }<a name="line.491"></a>
-<span class="sourceLineNo">492</span><a name="line.492"></a>
-<span class="sourceLineNo">493</span>  /**<a name="line.493"></a>
-<span class="sourceLineNo">494</span>   * Returns locality weighted by region size in MB. Will create locality cache if it does not<a name="line.494"></a>
-<span class="sourceLineNo">495</span>   * already exist.<a name="line.495"></a>
-<span class="sourceLineNo">496</span>   */<a name="line.496"></a>
-<span class="sourceLineNo">497</span>  public double getOrComputeWeightedLocality(int region, int server,<a name="line.497"></a>
-<span class="sourceLineNo">498</span>    BalancerClusterState.LocalityType type) {<a name="line.498"></a>
-<span class="sourceLineNo">499</span>    return getRegionSizeMB(region) * getOrComputeLocality(region, server, type);<a name="line.499"></a>
-<span class="sourceLineNo">500</span>  }<a name="line.500"></a>
-<span class="sourceLineNo">501</span><a name="line.501"></a>
-<span class="sourceLineNo">502</span>  /**<a name="line.502"></a>
-<span class="sourceLineNo">503</span>   * Returns the size in MB from the most recent RegionLoad for region<a name="line.503"></a>
-<span class="sourceLineNo">504</span>   */<a name="line.504"></a>
-<span class="sourceLineNo">505</span>  public int getRegionSizeMB(int region) {<a name="line.505"></a>
-<span class="sourceLineNo">506</span>    Deque&lt;BalancerRegionLoad&gt; load = regionLoads[region];<a name="line.506"></a>
-<span class="sourceLineNo">507</span>    // This means regions have no actual data on disk<a name="line.507"></a>
-<span class="sourceLineNo">508</span>    if (load == null) {<a name="line.508"></a>
-<span class="sourceLineNo">509</span>      return 0;<a name="line.509"></a>
-<span class="sourceLineNo">510</span>    }<a name="line.510"></a>
-<span class="sourceLineNo">511</span>    return regionLoads[region].getLast().getStorefileSizeMB();<a name="line.511"></a>
-<span class="sourceLineNo">512</span>  }<a name="line.512"></a>
-<span class="sourceLineNo">513</span><a name="line.513"></a>
-<span class="sourceLineNo">514</span>  /**<a name="line.514"></a>
-<span class="sourceLineNo">515</span>   * Computes and caches the locality for each region/rack combinations, as well as storing a<a name="line.515"></a>
-<span class="sourceLineNo">516</span>   * mapping of region -&gt; server and region -&gt; rack such that server and rack have the highest<a name="line.516"></a>
-<span class="sourceLineNo">517</span>   * locality for region<a name="line.517"></a>
-<span class="sourceLineNo">518</span>   */<a name="line.518"></a>
-<span class="sourceLineNo">519</span>  private void computeCachedLocalities() {<a name="line.519"></a>
-<span class="sourceLineNo">520</span>    rackLocalities = new float[numRegions][numRacks];<a name="line.520"></a>
-<span class="sourceLineNo">521</span>    regionsToMostLocalEntities = new int[LocalityType.values().length][numRegions];<a name="line.521"></a>
-<span class="sourceLineNo">522</span><a name="line.522"></a>
-<span class="sourceLineNo">523</span>    // Compute localities and find most local server per region<a name="line.523"></a>
-<span class="sourceLineNo">524</span>    for (int region = 0; region &lt; numRegions; region++) {<a name="line.524"></a>
-<span class="sourceLineNo">525</span>      int serverWithBestLocality = 0;<a name="line.525"></a>
-<span class="sourceLineNo">526</span>      float bestLocalityForRegion = 0;<a name="line.526"></a>
-<span class="sourceLineNo">527</span>      for (int server = 0; server &lt; numServers; server++) {<a name="line.527"></a>
-<span class="sourceLineNo">528</span>        // Aggregate per-rack locality<a name="line.528"></a>
-<span class="sourceLineNo">529</span>        float locality = getLocalityOfRegion(region, server);<a name="line.529"></a>
-<span class="sourceLineNo">530</span>        int rack = serverIndexToRackIndex[server];<a name="line.530"></a>
-<span class="sourceLineNo">531</span>        int numServersInRack = serversPerRack[rack].length;<a name="line.531"></a>
-<span class="sourceLineNo">532</span>        rackLocalities[region][rack] += locality / numServersInRack;<a name="line.532"></a>
-<span class="sourceLineNo">533</span><a name="line.533"></a>
-<span class="sourceLineNo">534</span>        if (locality &gt; bestLocalityForRegion) {<a name="line.534"></a>
-<span class="sourceLineNo">535</span>          serverWithBestLocality = server;<a name="line.535"></a>
-<span class="sourceLineNo">536</span>          bestLocalityForRegion = locality;<a name="line.536"></a>
-<span class="sourceLineNo">537</span>        }<a name="line.537"></a>
-<span class="sourceLineNo">538</span>      }<a name="line.538"></a>
-<span class="sourceLineNo">539</span>      regionsToMostLocalEntities[LocalityType.SERVER.ordinal()][region] = serverWithBestLocality;<a name="line.539"></a>
-<span class="sourceLineNo">540</span><a name="line.540"></a>
-<span class="sourceLineNo">541</span>      // Find most local rack per region<a name="line.541"></a>
-<span class="sourceLineNo">542</span>      int rackWithBestLocality = 0;<a name="line.542"></a>
-<span class="sourceLineNo">543</span>      float bestRackLocalityForRegion = 0.0f;<a name="line.543"></a>
-<span class="sourceLineNo">544</span>      for (int rack = 0; rack &lt; numRacks; rack++) {<a name="line.544"></a>
-<span class="sourceLineNo">545</span>        float rackLocality = rackLocalities[region][rack];<a name="line.545"></a>
-<span class="sourceLineNo">546</span>        if (rackLocality &gt; bestRackLocalityForRegion) {<a name="line.546"></a>
-<span class="sourceLineNo">547</span>          bestRackLocalityForRegion = rackLocality;<a name="line.547"></a>
-<span class="sourceLineNo">548</span>          rackWithBestLocality = rack;<a name="line.548"></a>
-<span class="sourceLineNo">549</span>        }<a name="line.549"></a>
-<span class="sourceLineNo">550</span>      }<a name="line.550"></a>
-<span class="sourceLineNo">551</span>      regionsToMostLocalEntities[LocalityType.RACK.ordinal()][region] = rackWithBestLocality;<a name="line.551"></a>
-<span class="sourceLineNo">552</span>    }<a name="line.552"></a>
-<span class="sourceLineNo">553</span><a name="line.553"></a>
-<span class="sourceLineNo">554</span>  }<a name="line.554"></a>
-<span class="sourceLineNo">555</span><a name="line.555"></a>
-<span class="sourceLineNo">556</span>  /**<a name="line.556"></a>
-<span class="sourceLineNo">557</span>   * Maps region index to rack index<a name="line.557"></a>
-<span class="sourceLineNo">558</span>   */<a name="line.558"></a>
-<span class="sourceLineNo">559</span>  public int getRackForRegion(int region) {<a name="line.559"></a>
-<span class="sourceLineNo">560</span>    return serverIndexToRackIndex[regionIndexToServerIndex[region]];<a name="line.560"></a>
-<span class="sourceLineNo">561</span>  }<a name="line.561"></a>
-<span class="sourceLineNo">562</span><a name="line.562"></a>
-<span class="sourceLineNo">563</span>  enum LocalityType {<a name="line.563"></a>
-<span class="sourceLineNo">564</span>    SERVER, RACK<a name="line.564"></a>
-<span class="sourceLineNo">565</span>  }<a name="line.565"></a>
-<span class="sourceLineNo">566</span><a name="line.566"></a>
-<span class="sourceLineNo">567</span>  public void doAction(BalanceAction action) {<a name="line.567"></a>
-<span class="sourceLineNo">568</span>    switch (action.getType()) {<a name="line.568"></a>
-<span class="sourceLineNo">569</span>      case NULL:<a name="line.569"></a>
-<span class="sourceLineNo">570</span>        break;<a name="line.570"></a>
-<span class="sourceLineNo">571</span>      case ASSIGN_REGION:<a name="line.571"></a>
-<span class="sourceLineNo">572</span>        // FindBugs: Having the assert quietens FB BC_UNCONFIRMED_CAST warnings<a name="line.572"></a>
-<span class="sourceLineNo">573</span>        assert action instanceof AssignRegionAction : action.getClass();<a name="line.573"></a>
-<span class="sourceLineNo">574</span>        AssignRegionAction ar = (AssignRegionAction) action;<a name="line.574"></a>
-<span class="sourceLineNo">575</span>        regionsPerServer[ar.getServer()] =<a name="line.575"></a>
-<span class="sourceLineNo">576</span>          addRegion(regionsPerServer[ar.getServer()], ar.getRegion());<a name="line.576"></a>
-<span class="sourceLineNo">577</span>        regionMoved(ar.getRegion(), -1, ar.getServer());<a name="line.577"></a>
-<span class="sourceLineNo">578</span>        break;<a name="line.578"></a>
-<span class="sourceLineNo">579</span>      case MOVE_REGION:<a name="line.579"></a>
-<span class="sourceLineNo">580</span>        assert action instanceof MoveRegionAction : action.getClass();<a name="line.580"></a>
-<span class="sourceLineNo">581</span>        MoveRegionAction mra = (MoveRegionAction) action;<a name="line.581"></a>
-<span class="sourceLineNo">582</span>        regionsPerServer[mra.getFromServer()] =<a name="line.582"></a>
-<span class="sourceLineNo">583</span>          removeRegion(regionsPerServer[mra.getFromServer()], mra.getRegion());<a name="line.583"></a>
-<span class="sourceLineNo">584</span>        regionsPerServer[mra.getToServer()] =<a name="line.584"></a>
-<span class="sourceLineNo">585</span>          addRegion(regionsPerServer[mra.getToServer()], mra.getRegion());<a name="line.585"></a>
-<span class="sourceLineNo">586</span>        regionMoved(mra.getRegion(), mra.getFromServer(), mra.getToServer());<a name="line.586"></a>
+<span class="sourceLineNo">471</span>  public float getOrComputeLocality(int region, int entity,<a name="line.471"></a>
+<span class="sourceLineNo">472</span>    BalancerClusterState.LocalityType type) {<a name="line.472"></a>
+<span class="sourceLineNo">473</span>    switch (type) {<a name="line.473"></a>
+<span class="sourceLineNo">474</span>      case SERVER:<a name="line.474"></a>
+<span class="sourceLineNo">475</span>        return getLocalityOfRegion(region, entity);<a name="line.475"></a>
+<span class="sourceLineNo">476</span>      case RACK:<a name="line.476"></a>
+<span class="sourceLineNo">477</span>        return getOrComputeRackLocalities()[region][entity];<a name="line.477"></a>
+<span class="sourceLineNo">478</span>      default:<a name="line.478"></a>
+<span class="sourceLineNo">479</span>        throw new IllegalArgumentException("Unsupported LocalityType: " + type);<a name="line.479"></a>
+<span class="sourceLineNo">480</span>    }<a name="line.480"></a>
+<span class="sourceLineNo">481</span>  }<a name="line.481"></a>
+<span class="sourceLineNo">482</span><a name="line.482"></a>
+<span class="sourceLineNo">483</span>  /**<a name="line.483"></a>
+<span class="sourceLineNo">484</span>   * Returns locality weighted by region size in MB. Will create locality cache if it does not<a name="line.484"></a>
+<span class="sourceLineNo">485</span>   * already exist.<a name="line.485"></a>
+<span class="sourceLineNo">486</span>   */<a name="line.486"></a>
+<span class="sourceLineNo">487</span>  public double getOrComputeWeightedLocality(int region, int server,<a name="line.487"></a>
+<span class="sourceLineNo">488</span>    BalancerClusterState.LocalityType type) {<a name="line.488"></a>
+<span class="sourceLineNo">489</span>    return getRegionSizeMB(region) * getOrComputeLocality(region, server, type);<a name="line.489"></a>
+<span class="sourceLineNo">490</span>  }<a name="line.490"></a>
+<span class="sourceLineNo">491</span><a name="line.491"></a>
+<span class="sourceLineNo">492</span>  /**<a name="line.492"></a>
+<span class="sourceLineNo">493</span>   * Returns the size in MB from the most recent RegionLoad for region<a name="line.493"></a>
+<span class="sourceLineNo">494</span>   */<a name="line.494"></a>
+<span class="sourceLineNo">495</span>  public int getRegionSizeMB(int region) {<a name="line.495"></a>
+<span class="sourceLineNo">496</span>    Deque&lt;BalancerRegionLoad&gt; load = regionLoads[region];<a name="line.496"></a>
+<span class="sourceLineNo">497</span>    // This means regions have no actual data on disk<a name="line.497"></a>
+<span class="sourceLineNo">498</span>    if (load == null) {<a name="line.498"></a>
+<span class="sourceLineNo">499</span>      return 0;<a name="line.499"></a>
+<span class="sourceLineNo">500</span>    }<a name="line.500"></a>
+<span class="sourceLineNo">501</span>    return regionLoads[region].getLast().getStorefileSizeMB();<a name="line.501"></a>
+<span class="sourceLineNo">502</span>  }<a name="line.502"></a>
+<span class="sourceLineNo">503</span><a name="line.503"></a>
+<span class="sourceLineNo">504</span>  /**<a name="line.504"></a>
+<span class="sourceLineNo">505</span>   * Computes and caches the locality for each region/rack combinations, as well as storing a<a name="line.505"></a>
+<span class="sourceLineNo">506</span>   * mapping of region -&gt; server and region -&gt; rack such that server and rack have the highest<a name="line.506"></a>
+<span class="sourceLineNo">507</span>   * locality for region<a name="line.507"></a>
+<span class="sourceLineNo">508</span>   */<a name="line.508"></a>
+<span class="sourceLineNo">509</span>  private void computeCachedLocalities() {<a name="line.509"></a>
+<span class="sourceLineNo">510</span>    rackLocalities = new float[numRegions][numRacks];<a name="line.510"></a>
+<span class="sourceLineNo">511</span>    regionsToMostLocalEntities = new int[LocalityType.values().length][numRegions];<a name="line.511"></a>
+<span class="sourceLineNo">512</span><a name="line.512"></a>
+<span class="sourceLineNo">513</span>    // Compute localities and find most local server per region<a name="line.513"></a>
+<span class="sourceLineNo">514</span>    for (int region = 0; region &lt; numRegions; region++) {<a name="line.514"></a>
+<span class="sourceLineNo">515</span>      int serverWithBestLocality = 0;<a name="line.515"></a>
+<span class="sourceLineNo">516</span>      float bestLocalityForRegion = 0;<a name="line.516"></a>
+<span class="sourceLineNo">517</span>      for (int server = 0; server &lt; numServers; server++) {<a name="line.517"></a>
+<span class="sourceLineNo">518</span>        // Aggregate per-rack locality<a name="line.518"></a>
+<span class="sourceLineNo">519</span>        float locality = getLocalityOfRegion(region, server);<a name="line.519"></a>
+<span class="sourceLineNo">520</span>        int rack = serverIndexToRackIndex[server];<a name="line.520"></a>
+<span class="sourceLineNo">521</span>        int numServersInRack = serversPerRack[rack].length;<a name="line.521"></a>
+<span class="sourceLineNo">522</span>        rackLocalities[region][rack] += locality / numServersInRack;<a name="line.522"></a>
+<span class="sourceLineNo">523</span><a name="line.523"></a>
+<span class="sourceLineNo">524</span>        if (locality &gt; bestLocalityForRegion) {<a name="line.524"></a>
+<span class="sourceLineNo">525</span>          serverWithBestLocality = server;<a name="line.525"></a>
+<span class="sourceLineNo">526</span>          bestLocalityForRegion = locality;<a name="line.526"></a>
+<span class="sourceLineNo">527</span>        }<a name="line.527"></a>
+<span class="sourceLineNo">528</span>      }<a name="line.528"></a>
+<span class="sourceLineNo">529</span>      regionsToMostLocalEntities[LocalityType.SERVER.ordinal()][region] = serverWithBestLocality;<a name="line.529"></a>
+<span class="sourceLineNo">530</span><a name="line.530"></a>
+<span class="sourceLineNo">531</span>      // Find most local rack per region<a name="line.531"></a>
+<span class="sourceLineNo">532</span>      int rackWithBestLocality = 0;<a name="line.532"></a>
+<span class="sourceLineNo">533</span>      float bestRackLocalityForRegion = 0.0f;<a name="line.533"></a>
+<span class="sourceLineNo">534</span>      for (int rack = 0; rack &lt; numRacks; rack++) {<a name="line.534"></a>
+<span class="sourceLineNo">535</span>        float rackLocality = rackLocalities[region][rack];<a name="line.535"></a>
+<span class="sourceLineNo">536</span>        if (rackLocality &gt; bestRackLocalityForRegion) {<a name="line.536"></a>
+<span class="sourceLineNo">537</span>          bestRackLocalityForRegion = rackLocality;<a name="line.537"></a>
+<span class="sourceLineNo">538</span>          rackWithBestLocality = rack;<a name="line.538"></a>
+<span class="sourceLineNo">539</span>        }<a name="line.539"></a>
+<span class="sourceLineNo">540</span>      }<a name="line.540"></a>
+<span class="sourceLineNo">541</span>      regionsToMostLocalEntities[LocalityType.RACK.ordinal()][region] = rackWithBestLocality;<a name="line.541"></a>
+<span class="sourceLineNo">542</span>    }<a name="line.542"></a>
+<span class="sourceLineNo">543</span><a name="line.543"></a>
+<span class="sourceLineNo">544</span>  }<a name="line.544"></a>
+<span class="sourceLineNo">545</span><a name="line.545"></a>
+<span class="sourceLineNo">546</span>  /**<a name="line.546"></a>
+<span class="sourceLineNo">547</span>   * Maps region index to rack index<a name="line.547"></a>
+<span class="sourceLineNo">548</span>   */<a name="line.548"></a>
+<span class="sourceLineNo">549</span>  public int getRackForRegion(int region) {<a name="line.549"></a>
+<span class="sourceLineNo">550</span>    return serverIndexToRackIndex[regionIndexToServerIndex[region]];<a name="line.550"></a>
+<span class="sourceLineNo">551</span>  }<a name="line.551"></a>
+<span class="sourceLineNo">552</span><a name="line.552"></a>
+<span class="sourceLineNo">553</span>  enum LocalityType {<a name="line.553"></a>
+<span class="sourceLineNo">554</span>    SERVER, RACK<a name="line.554"></a>
+<span class="sourceLineNo">555</span>  }<a name="line.555"></a>
+<span class="sourceLineNo">556</span><a name="line.556"></a>
+<span class="sourceLineNo">557</span>  public void doAction(BalanceAction action) {<a name="line.557"></a>
+<span class="sourceLineNo">558</span>    switch (action.getType()) {<a name="line.558"></a>
+<span class="sourceLineNo">559</span>      case NULL:<a name="line.559"></a>
+<span class="sourceLineNo">560</span>        break;<a name="line.560"></a>
+<span class="sourceLineNo">561</span>      case ASSIGN_REGION:<a name="line.561"></a>
+<span class="sourceLineNo">562</span>        // FindBugs: Having the assert quietens FB BC_UNCONFIRMED_CAST warnings<a name="line.562"></a>
+<span class="sourceLineNo">563</span>        assert action instanceof AssignRegionAction : action.getClass();<a name="line.563"></a>
+<span class="sourceLineNo">564</span>        AssignRegionAction ar = (AssignRegionAction) action;<a name="line.564"></a>
+<span class="sourceLineNo">565</span>        regionsPerServer[ar.getServer()] =<a name="line.565"></a>
+<span class="sourceLineNo">566</span>          addRegion(regionsPerServer[ar.getServer()], ar.getRegion());<a name="line.566"></a>
+<span class="sourceLineNo">567</span>        regionMoved(ar.getRegion(), -1, ar.getServer());<a name="line.567"></a>
+<span class="sourceLineNo">568</span>        break;<a name="line.568"></a>
+<span class="sourceLineNo">569</span>      case MOVE_REGION:<a name="line.569"></a>
+<span class="sourceLineNo">570</span>        assert action instanceof MoveRegionAction : action.getClass();<a name="line.570"></a>
+<span class="sourceLineNo">571</span>        MoveRegionAction mra = (MoveRegionAction) action;<a name="line.571"></a>
+<span class="sourceLineNo">572</span>        regionsPerServer[mra.getFromServer()] =<a name="line.572"></a>
+<span class="sourceLineNo">573</span>          removeRegion(regionsPerServer[mra.getFromServer()], mra.getRegion());<a name="line.573"></a>
+<span class="sourceLineNo">574</span>        regionsPerServer[mra.getToServer()] =<a name="line.574"></a>
+<span class="sourceLineNo">575</span>          addRegion(regionsPerServer[mra.getToServer()], mra.getRegion());<a name="line.575"></a>
+<span class="sourceLineNo">576</span>        regionMoved(mra.getRegion(), mra.getFromServer(), mra.getToServer());<a name="line.576"></a>
+<span class="sourceLineNo">577</span>        break;<a name="line.577"></a>
+<span class="sourceLineNo">578</span>      case SWAP_REGIONS:<a name="line.578"></a>
+<span class="sourceLineNo">579</span>        assert action instanceof SwapRegionsAction : action.getClass();<a name="line.579"></a>
+<span class="sourceLineNo">580</span>        SwapRegionsAction a = (SwapRegionsAction) action;<a name="line.580"></a>
+<span class="sourceLineNo">581</span>        regionsPerServer[a.getFromServer()] =<a name="line.581"></a>
+<span class="sourceLineNo">582</span>          replaceRegion(regionsPerServer[a.getFromServer()], a.getFromRegion(), a.getToRegion());<a name="line.582"></a>
+<span class="sourceLineNo">583</span>        regionsPerServer[a.getToServer()] =<a name="line.583"></a>
+<span class="sourceLineNo">584</span>          replaceRegion(regionsPerServer[a.getToServer()], a.getToRegion(), a.getFromRegion());<a name="line.584"></a>
+<span class="sourceLineNo">585</span>        regionMoved(a.getFromRegion(), a.getFromServer(), a.getToServer());<a name="line.585"></a>
+<span class="sourceLineNo">586</span>        regionMoved(a.getToRegion(), a.getToServer(), a.getFromServer());<a name="line.586"></a>
 <span class="sourceLineNo">587</span>        break;<a name="line.587"></a>
-<span class="sourceLineNo">588</span>      case SWAP_REGIONS:<a name="line.588"></a>
-<span class="sourceLineNo">589</span>        assert action instanceof SwapRegionsAction : action.getClass();<a name="line.589"></a>
-<span class="sourceLineNo">590</span>        SwapRegionsAction a = (SwapRegionsAction) action;<a name="line.590"></a>
-<span class="sourceLineNo">591</span>        regionsPerServer[a.getFromServer()] =<a name="line.591"></a>
-<span class="sourceLineNo">592</span>          replaceRegion(regionsPerServer[a.getFromServer()], a.getFromRegion(), a.getToRegion());<a name="line.592"></a>
-<span class="sourceLineNo">593</span>        regionsPerServer[a.getToServer()] =<a name="line.593"></a>
-<span class="sourceLineNo">594</span>          replaceRegion(regionsPerServer[a.getToServer()], a.getToRegion(), a.getFromRegion());<a name="line.594"></a>
-<span class="sourceLineNo">595</span>        regionMoved(a.getFromRegion(), a.getFromServer(), a.getToServer());<a name="line.595"></a>
-<span class="sourceLineNo">596</span>        regionMoved(a.getToRegion(), a.getToServer(), a.getFromServer());<a name="line.596"></a>
-<span class="sourceLineNo">597</span>        break;<a name="line.597"></a>
-<span class="sourceLineNo">598</span>      default:<a name="line.598"></a>
-<span class="sourceLineNo">599</span>        throw new RuntimeException("Uknown action:" + action.getType());<a name="line.599"></a>
-<span class="sourceLineNo">600</span>    }<a name="line.600"></a>
-<span class="sourceLineNo">601</span>  }<a name="line.601"></a>
-<span class="sourceLineNo">602</span><a name="line.602"></a>
-<span class="sourceLineNo">603</span>  /**<a name="line.603"></a>
-<span class="sourceLineNo">604</span>   * Return true if the placement of region on server would lower the availability of the region in<a name="line.604"></a>
-<span class="sourceLineNo">605</span>   * question<a name="line.605"></a>
-<span class="sourceLineNo">606</span>   * @return true or false<a name="line.606"></a>
-<span class="sourceLineNo">607</span>   */<a name="line.607"></a>
-<span class="sourceLineNo">608</span>  boolean wouldLowerAvailability(RegionInfo regionInfo, ServerName serverName) {<a name="line.608"></a>
-<span class="sourceLineNo">609</span>    if (!serversToIndex.containsKey(serverName.getAddress())) {<a name="line.609"></a>
-<span class="sourceLineNo">610</span>      return false; // safeguard against race between cluster.servers and servers from LB method<a name="line.610"></a>
-<span class="sourceLineNo">611</span>                    // args<a name="line.611"></a>
+<span class="sourceLineNo">588</span>      default:<a name="line.588"></a>
+<span class="sourceLineNo">589</span>        throw new RuntimeException("Uknown action:" + action.getType());<a name="line.589"></a>
+<span class="sourceLineNo">590</span>    }<a name="line.590"></a>
+<span class="sourceLineNo">591</span>  }<a name="line.591"></a>
+<span class="sourceLineNo">592</span><a name="line.592"></a>
+<span class="sourceLineNo">593</span>  /**<a name="line.593"></a>
+<span class="sourceLineNo">594</span>   * Return true if the placement of region on server would lower the availability of the region in<a name="line.594"></a>
+<span class="sourceLineNo">595</span>   * question<a name="line.595"></a>
+<span class="sourceLineNo">596</span>   * @return true or false<a name="line.596"></a>
+<span class="sourceLineNo">597</span>   */<a name="line.597"></a>
+<span class="sourceLineNo">598</span>  boolean wouldLowerAvailability(RegionInfo regionInfo, ServerName serverName) {<a name="line.598"></a>
+<span class="sourceLineNo">599</span>    if (!serversToIndex.containsKey(serverName.getAddress())) {<a name="line.599"></a>
+<span class="sourceLineNo">600</span>      return false; // safeguard against race between cluster.servers and servers from LB method<a name="line.600"></a>
+<span class="sourceLineNo">601</span>      // args<a name="line.601"></a>
+<span class="sourceLineNo">602</span>    }<a name="line.602"></a>
+<span class="sourceLineNo">603</span>    int server = serversToIndex.get(serverName.getAddress());<a name="line.603"></a>
+<span class="sourceLineNo">604</span>    int region = regionsToIndex.get(regionInfo);<a name="line.604"></a>
+<span class="sourceLineNo">605</span><a name="line.605"></a>
+<span class="sourceLineNo">606</span>    // Region replicas for same region should better assign to different servers<a name="line.606"></a>
+<span class="sourceLineNo">607</span>    for (int i : regionsPerServer[server]) {<a name="line.607"></a>
+<span class="sourceLineNo">608</span>      RegionInfo otherRegionInfo = regions[i];<a name="line.608"></a>
+<span class="sourceLineNo">609</span>      if (RegionReplicaUtil.isReplicasForSameRegion(regionInfo, otherRegionInfo)) {<a name="line.609"></a>
+<span class="sourceLineNo">610</span>        return true;<a name="line.610"></a>
+<span class="sourceLineNo">611</span>      }<a name="line.611"></a>
 <span class="sourceLineNo">612</span>    }<a name="line.612"></a>
-<span class="sourceLineNo">613</span>    int server = serversToIndex.get(serverName.getAddress());<a name="line.613"></a>
-<span class="sourceLineNo">614</span>    int region = regionsToIndex.get(regionInfo);<a name="line.614"></a>
-<span class="sourceLineNo">615</span><a name="line.615"></a>
-<span class="sourceLineNo">616</span>    // Region replicas for same region should better assign to different servers<a name="line.616"></a>
-<span class="sourceLineNo">617</span>    for (int i : regionsPerServer[server]) {<a name="line.617"></a>
-<span class="sourceLineNo">618</span>      RegionInfo otherRegionInfo = regions[i];<a name="line.618"></a>
-<span class="sourceLineNo">619</span>      if (RegionReplicaUtil.isReplicasForSameRegion(regionInfo, otherRegionInfo)) {<a name="line.619"></a>
-<span class="sourceLineNo">620</span>        return true;<a name="line.620"></a>
-<span class="sourceLineNo">621</span>      }<a name="line.621"></a>
-<span class="sourceLineNo">622</span>    }<a name="line.622"></a>
-<span class="sourceLineNo">623</span><a name="line.623"></a>
-<span class="sourceLineNo">624</span>    int primary = regionIndexToPrimaryIndex[region];<a name="line.624"></a>
-<span class="sourceLineNo">625</span>    if (primary == -1) {<a name="line.625"></a>
-<span class="sourceLineNo">626</span>      return false;<a name="line.626"></a>
-<span class="sourceLineNo">627</span>    }<a name="line.627"></a>
-<span class="sourceLineNo">628</span>    // there is a subset relation for server &lt; host &lt; rack<a name="line.628"></a>
-<span class="sourceLineNo">629</span>    // check server first<a name="line.629"></a>
-<span class="sourceLineNo">630</span>    if (contains(primariesOfRegionsPerServer[server], primary)) {<a name="line.630"></a>
-<span class="sourceLineNo">631</span>      // check for whether there are other servers that we can place this region<a name="line.631"></a>
-<span class="sourceLineNo">632</span>      for (int i = 0; i &lt; primariesOfRegionsPerServer.length; i++) {<a name="line.632"></a>
-<span class="sourceLineNo">633</span>        if (i != server &amp;&amp; !contains(primariesOfRegionsPerServer[i], primary)) {<a name="line.633"></a>
-<span class="sourceLineNo">634</span>          return true; // meaning there is a better server<a name="line.634"></a>
-<span class="sourceLineNo">635</span>        }<a name="line.635"></a>
-<span class="sourceLineNo">636</span>      }<a name="line.636"></a>
-<span class="sourceLineNo">637</span>      return false; // there is not a better server to place this<a name="line.637"></a>
-<span class="sourceLineNo">638</span>    }<a name="line.638"></a>
-<span class="sourceLineNo">639</span><a name="line.639"></a>
-<span class="sourceLineNo">640</span>    // check host<a name="line.640"></a>
-<span class="sourceLineNo">641</span>    if (multiServersPerHost) {<a name="line.641"></a>
-<span class="sourceLineNo">642</span>      // these arrays would only be allocated if we have more than one server per host<a name="line.642"></a>
-<span class="sourceLineNo">643</span>      int host = serverIndexToHostIndex[server];<a name="line.643"></a>
-<span class="sourceLineNo">644</span>      if (contains(primariesOfRegionsPerHost[host], primary)) {<a name="line.644"></a>
-<span class="sourceLineNo">645</span>        // check for whether there are other hosts that we can place this region<a name="line.645"></a>
-<span class="sourceLineNo">646</span>        for (int i = 0; i &lt; primariesOfRegionsPerHost.length; i++) {<a name="line.646"></a>
-<span class="sourceLineNo">647</span>          if (i != host &amp;&amp; !contains(primariesOfRegionsPerHost[i], primary)) {<a name="line.647"></a>
-<span class="sourceLineNo">648</span>            return true; // meaning there is a better host<a name="line.648"></a>
-<span class="sourceLineNo">649</span>          }<a name="line.649"></a>
-<span class="sourceLineNo">650</span>        }<a name="line.650"></a>
-<span class="sourceLineNo">651</span>        return false; // there is not a better host to place this<a name="line.651"></a>
-<span class="sourceLineNo">652</span>      }<a name="line.652"></a>
-<span class="sourceLineNo">653</span>    }<a name="line.653"></a>
-<span class="sourceLineNo">654</span><a name="line.654"></a>
-<span class="sourceLineNo">655</span>    // check rack<a name="line.655"></a>
-<span class="sourceLineNo">656</span>    if (numRacks &gt; 1) {<a name="line.656"></a>
-<span class="sourceLineNo">657</span>      int rack = serverIndexToRackIndex[server];<a name="line.657"></a>
-<span class="sourceLineNo">658</span>      if (contains(primariesOfRegionsPerRack[rack], primary)) {<a name="line.658"></a>
-<span class="sourceLineNo">659</span>        // check for whether there are other racks that we can place this region<a name="line.659"></a>
-<span class="sourceLineNo">660</span>        for (int i = 0; i &lt; primariesOfRegionsPerRack.length; i++) {<a name="line.660"></a>
-<span class="sourceLineNo">661</span>          if (i != rack &amp;&amp; !contains(primariesOfRegionsPerRack[i], primary)) {<a name="line.661"></a>
-<span class="sourceLineNo">662</span>            return true; // meaning there is a better rack<a name="line.662"></a>
-<span class="sourceLineNo">663</span>          }<a name="line.663"></a>
-<span class="sourceLineNo">664</span>        }<a name="line.664"></a>
-<span class="sourceLineNo">665</span>        return false; // there is not a better rack to place this<a name="line.665"></a>
-<span class="sourceLineNo">666</span>      }<a name="line.666"></a>
-<span class="sourceLineNo">667</span>    }<a name="line.667"></a>
-<span class="sourceLineNo">668</span><a name="line.668"></a>
-<span class="sourceLineNo">669</span>    return false;<a name="line.669"></a>
-<span class="sourceLineNo">670</span>  }<a name="line.670"></a>
-<span class="sourceLineNo">671</span><a name="line.671"></a>
-<span class="sourceLineNo">672</span>  void doAssignRegion(RegionInfo regionInfo, ServerName serverName) {<a name="line.672"></a>
-<span class="sourceLineNo">673</span>    if (!serversToIndex.containsKey(serverName.getAddress())) {<a name="line.673"></a>
-<span class="sourceLineNo">674</span>      return;<a name="line.674"></a>
-<span class="sourceLineNo">675</span>    }<a name="line.675"></a>
-<span class="sourceLineNo">676</span>    int server = serversToIndex.get(serverName.getAddress());<a name="line.676"></a>
-<span class="sourceLineNo">677</span>    int region = regionsToIndex.get(regionInfo);<a name="line.677"></a>
-<span class="sourceLineNo">678</span>    doAction(new AssignRegionAction(region, server));<a name="line.678"></a>
-<span class="sourceLineNo">679</span>  }<a name="line.679"></a>
-<span class="sourceLineNo">680</span><a name="line.680"></a>
-<span class="sourceLineNo">681</span>  void regionMoved(int region, int oldServer, int newServer) {<a name="line.681"></a>
-<span class="sourceLineNo">682</span>    regionIndexToServerIndex[region] = newServer;<a name="line.682"></a>
-<span class="sourceLineNo">683</span>    if (initialRegionIndexToServerIndex[region] == newServer) {<a name="line.683"></a>
-<span class="sourceLineNo">684</span>      numMovedRegions--; // region moved back to original location<a name="line.684"></a>
-<span class="sourceLineNo">685</span>    } else if (oldServer &gt;= 0 &amp;&amp; initialRegionIndexToServerIndex[region] == oldServer) {<a name="line.685"></a>
-<span class="sourceLineNo">686</span>      numMovedRegions++; // region moved from original location<a name="line.686"></a>
-<span class="sourceLineNo">687</span>    }<a name="line.687"></a>
-<span class="sourceLineNo">688</span>    int tableIndex = regionIndexToTableIndex[region];<a name="line.688"></a>
-<span class="sourceLineNo">689</span>    if (oldServer &gt;= 0) {<a name="line.689"></a>
-<span class="sourceLineNo">690</span>      numRegionsPerServerPerTable[oldServer][tableIndex]--;<a name="line.690"></a>
-<span class="sourceLineNo">691</span>      // update regionSkewPerTable for the move from old server<a name="line.691"></a>
-<span class="sourceLineNo">692</span>      regionSkewByTable[tableIndex] += getSkewChangeFor(oldServer, tableIndex, -1);<a name="line.692"></a>
-<span class="sourceLineNo">693</span>    }<a name="line.693"></a>
-<span class="sourceLineNo">694</span>    numRegionsPerServerPerTable[newServer][tableIndex]++;<a name="line.694"></a>
-<span class="sourceLineNo">695</span><a name="line.695"></a>
-<span class="sourceLineNo">696</span>    // update regionSkewPerTable for the move to new server<a name="line.696"></a>
-<span class="sourceLineNo">697</span>    regionSkewByTable[tableIndex] += getSkewChangeFor(newServer, tableIndex, 1);<a name="line.697"></a>
+<span class="sourceLineNo">613</span><a name="line.613"></a>
+<span class="sourceLineNo">614</span>    int primary = regionIndexToPrimaryIndex[region];<a name="line.614"></a>
+<span class="sourceLineNo">615</span>    if (primary == -1) {<a name="line.615"></a>
+<span class="sourceLineNo">616</span>      return false;<a name="line.616"></a>
+<span class="sourceLineNo">617</span>    }<a name="line.617"></a>
+<span class="sourceLineNo">618</span>    // there is a subset relation for server &lt; host &lt; rack<a name="line.618"></a>
+<span class="sourceLineNo">619</span>    // check server first<a name="line.619"></a>
+<span class="sourceLineNo">620</span>    int result = checkLocationForPrimary(server, colocatedReplicaCountsPerServer, primary);<a name="line.620"></a>
+<span class="sourceLineNo">621</span>    if (result != 0) {<a name="line.621"></a>
+<span class="sourceLineNo">622</span>      return result &gt; 0;<a name="line.622"></a>
+<span class="sourceLineNo">623</span>    }<a name="line.623"></a>
+<span class="sourceLineNo">624</span><a name="line.624"></a>
+<span class="sourceLineNo">625</span>    // check host<a name="line.625"></a>
+<span class="sourceLineNo">626</span>    if (multiServersPerHost) {<a name="line.626"></a>
+<span class="sourceLineNo">627</span>      result = checkLocationForPrimary(serverIndexToHostIndex[server],<a name="line.627"></a>
+<span class="sourceLineNo">628</span>        colocatedReplicaCountsPerHost, primary);<a name="line.628"></a>
+<span class="sourceLineNo">629</span>      if (result != 0) {<a name="line.629"></a>
+<span class="sourceLineNo">630</span>        return result &gt; 0;<a name="line.630"></a>
+<span class="sourceLineNo">631</span>      }<a name="line.631"></a>
+<span class="sourceLineNo">632</span>    }<a name="line.632"></a>
+<span class="sourceLineNo">633</span><a name="line.633"></a>
+<span class="sourceLineNo">634</span>    // check rack<a name="line.634"></a>
+<span class="sourceLineNo">635</span>    if (numRacks &gt; 1) {<a name="line.635"></a>
+<span class="sourceLineNo">636</span>      result = checkLocationForPrimary(serverIndexToRackIndex[server],<a name="line.636"></a>
+<span class="sourceLineNo">637</span>        colocatedReplicaCountsPerRack, primary);<a name="line.637"></a>
+<span class="sourceLineNo">638</span>      if (result != 0) {<a name="line.638"></a>
+<span class="sourceLineNo">639</span>        return result &gt; 0;<a name="line.639"></a>
+<span class="sourceLineNo">640</span>      }<a name="line.640"></a>
+<span class="sourceLineNo">641</span>    }<a name="line.641"></a>
+<span class="sourceLineNo">642</span>    return false;<a name="line.642"></a>
+<span class="sourceLineNo">643</span>  }<a name="line.643"></a>
+<span class="sourceLineNo">644</span><a name="line.644"></a>
+<span class="sourceLineNo">645</span>  /**<a name="line.645"></a>
+<span class="sourceLineNo">646</span>   * Common method for better solution check.<a name="line.646"></a>
+<span class="sourceLineNo">647</span>   * @param colocatedReplicaCountsPerLocation colocatedReplicaCountsPerHost or<a name="line.647"></a>
+<span class="sourceLineNo">648</span>   *                                          colocatedReplicaCountsPerRack<a name="line.648"></a>
+<span class="sourceLineNo">649</span>   * @return 1 for better, -1 for no better, 0 for unknown<a name="line.649"></a>
+<span class="sourceLineNo">650</span>   */<a name="line.650"></a>
+<span class="sourceLineNo">651</span>  private int checkLocationForPrimary(int location,<a name="line.651"></a>
+<span class="sourceLineNo">652</span>    Int2IntCounterMap[] colocatedReplicaCountsPerLocation, int primary) {<a name="line.652"></a>
+<span class="sourceLineNo">653</span>    if (colocatedReplicaCountsPerLocation[location].containsKey(primary)) {<a name="line.653"></a>
+<span class="sourceLineNo">654</span>      // check for whether there are other Locations that we can place this region<a name="line.654"></a>
+<span class="sourceLineNo">655</span>      for (int i = 0; i &lt; colocatedReplicaCountsPerLocation.length; i++) {<a name="line.655"></a>
+<span class="sourceLineNo">656</span>        if (i != location &amp;&amp; !colocatedReplicaCountsPerLocation[i].containsKey(primary)) {<a name="line.656"></a>
+<span class="sourceLineNo">657</span>          return 1; // meaning there is a better Location<a name="line.657"></a>
+<span class="sourceLineNo">658</span>        }<a name="line.658"></a>
+<span class="sourceLineNo">659</span>      }<a name="line.659"></a>
+<span class="sourceLineNo">660</span>      return -1; // there is not a better Location to place this<a name="line.660"></a>
+<span class="sourceLineNo">661</span>    }<a name="line.661"></a>
+<span class="sourceLineNo">662</span>    return 0;<a name="line.662"></a>
+<span class="sourceLineNo">663</span>  }<a name="line.663"></a>
+<span class="sourceLineNo">664</span><a name="line.664"></a>
+<span class="sourceLineNo">665</span>  void doAssignRegion(RegionInfo regionInfo, ServerName serverName) {<a name="line.665"></a>
+<span class="sourceLineNo">666</span>    if (!serversToIndex.containsKey(serverName.getAddress())) {<a name="line.666"></a>
+<span class="sourceLineNo">667</span>      return;<a name="line.667"></a>
+<span class="sourceLineNo">668</span>    }<a name="line.668"></a>
+<span class="sourceLineNo">669</span>    int server = serversToIndex.get(serverName.getAddress());<a name="line.669"></a>
+<span class="sourceLineNo">670</span>    int region = regionsToIndex.get(regionInfo);<a name="line.670"></a>
+<span class="sourceLineNo">671</span>    doAction(new AssignRegionAction(region, server));<a name="line.671"></a>
+<span class="sourceLineNo">672</span>  }<a name="line.672"></a>
+<span class="sourceLineNo">673</span><a name="line.673"></a>
+<span class="sourceLineNo">674</span>  void regionMoved(int region, int oldServer, int newServer) {<a name="line.674"></a>
+<span class="sourceLineNo">675</span>    regionIndexToServerIndex[region] = newServer;<a name="line.675"></a>
+<span class="sourceLineNo">676</span>    if (initialRegionIndexToServerIndex[region] == newServer) {<a name="line.676"></a>
+<span class="sourceLineNo">677</span>      numMovedRegions--; // region moved back to original location<a name="line.677"></a>
+<span class="sourceLineNo">678</span>    } else if (oldServer &gt;= 0 &amp;&amp; initialRegionIndexToServerIndex[region] == oldServer) {<a name="line.678"></a>
+<span class="sourceLineNo">679</span>      numMovedRegions++; // region moved from original location<a name="line.679"></a>
+<span class="sourceLineNo">680</span>    }<a name="line.680"></a>
+<span class="sourceLineNo">681</span>    int tableIndex = regionIndexToTableIndex[region];<a name="line.681"></a>
+<span class="sourceLineNo">682</span>    if (oldServer &gt;= 0) {<a name="line.682"></a>
+<span class="sourceLineNo">683</span>      numRegionsPerServerPerTable[oldServer][tableIndex]--;<a name="line.683"></a>
+<span class="sourceLineNo">684</span>      // update regionSkewPerTable for the move from old server<a name="line.684"></a>
+<span class="sourceLineNo">685</span>      regionSkewByTable[tableIndex] += getSkewChangeFor(oldServer, tableIndex, -1);<a name="line.685"></a>
+<span class="sourceLineNo">686</span>    }<a name="line.686"></a>
+<span class="sourceLineNo">687</span>    numRegionsPerServerPerTable[newServer][tableIndex]++;<a name="line.687"></a>
+<span class="sourceLineNo">688</span><a name="line.688"></a>
+<span class="sourceLineNo">689</span>    // update regionSkewPerTable for the move to new server<a name="line.689"></a>
+<span class="sourceLineNo">690</span>    regionSkewByTable[tableIndex] += getSkewChangeFor(newServer, tableIndex, 1);<a name="line.690"></a>
+<span class="sourceLineNo">691</span><a name="line.691"></a>
+<span class="sourceLineNo">692</span>    // update for servers<a name="line.692"></a>
+<span class="sourceLineNo">693</span>    int primary = regionIndexToPrimaryIndex[region];<a name="line.693"></a>
+<span class="sourceLineNo">694</span>    if (oldServer &gt;= 0) {<a name="line.694"></a>
+<span class="sourceLineNo">695</span>      colocatedReplicaCountsPerServer[oldServer].getAndDecrement(primary);<a name="line.695"></a>
+<span class="sourceLineNo">696</span>    }<a name="line.696"></a>
+<span class="sourceLineNo">697</span>    colocatedReplicaCountsPerServer[newServer].getAndIncrement(primary);<a name="line.697"></a>
 <span class="sourceLineNo">698</span><a name="line.698"></a>
-<span class="sourceLineNo">699</span>    // update for servers<a name="line.699"></a>
-<span class="sourceLineNo">700</span>    int primary = regionIndexToPrimaryIndex[region];<a name="line.700"></a>
-<span class="sourceLineNo">701</span>    if (oldServer &gt;= 0) {<a name="line.701"></a>
-<span class="sourceLineNo">702</span>      primariesOfRegionsPerServer[oldServer] =<a name="line.702"></a>
-<span class="sourceLineNo">703</span>        removeRegion(primariesOfRegionsPerServer[oldServer], primary);<a name="line.703"></a>
-<span class="sourceLineNo">704</span>    }<a name="line.704"></a>
-<span class="sourceLineNo">705</span>    primariesOfRegionsPerServer[newServer] =<a name="line.705"></a>
-<span class="sourceLineNo">706</span>      addRegionSorted(primariesOfRegionsPerServer[newServer], primary);<a name="line.706"></a>
-<span class="sourceLineNo">707</span><a name="line.707"></a>
-<span class="sourceLineNo">708</span>    // update for hosts<a name="line.708"></a>
-<span class="sourceLineNo">709</span>    if (multiServersPerHost) {<a name="line.709"></a>
-<span class="sourceLineNo">710</span>      int oldHost = oldServer &gt;= 0 ? serverIndexToHostIndex[oldServer] : -1;<a name="line.710"></a>
-<span class="sourceLineNo">711</span>      int newHost = serverIndexToHostIndex[newServer];<a name="line.711"></a>
-<span class="sourceLineNo">712</span>      if (newHost != oldHost) {<a name="line.712"></a>
-<span class="sourceLineNo">713</span>        regionsPerHost[newHost] = addRegion(regionsPerHost[newHost], region);<a name="line.713"></a>
-<span class="sourceLineNo">714</span>        primariesOfRegionsPerHost[newHost] =<a name="line.714"></a>
-<span class="sourceLineNo">715</span>          addRegionSorted(primariesOfRegionsPerHost[newHost], primary);<a name="line.715"></a>
-<span class="sourceLineNo">716</span>        if (oldHost &gt;= 0) {<a name="line.716"></a>
-<span class="sourceLineNo">717</span>          regionsPerHost[oldHost] = removeRegion(regionsPerHost[oldHost], region);<a name="line.717"></a>
-<span class="sourceLineNo">718</span>          primariesOfRegionsPerHost[oldHost] =<a name="line.718"></a>
-<span class="sourceLineNo">719</span>            removeRegion(primariesOfRegionsPerHost[oldHost], primary); // will still be sorted<a name="line.719"></a>
-<span class="sourceLineNo">720</span>        }<a name="line.720"></a>
-<span class="sourceLineNo">721</span>      }<a name="line.721"></a>
-<span class="sourceLineNo">722</span>    }<a name="line.722"></a>
-<span class="sourceLineNo">723</span><a name="line.723"></a>
-<span class="sourceLineNo">724</span>    // update for racks<a name="line.724"></a>
-<span class="sourceLineNo">725</span>    if (numRacks &gt; 1) {<a name="line.725"></a>
-<span class="sourceLineNo">726</span>      int oldRack = oldServer &gt;= 0 ? serverIndexToRackIndex[oldServer] : -1;<a name="line.726"></a>
-<span class="sourceLineNo">727</span>      int newRack = serverIndexToRackIndex[newServer];<a name="line.727"></a>
-<span class="sourceLineNo">728</span>      if (newRack != oldRack) {<a name="line.728"></a>
-<span class="sourceLineNo">729</span>        regionsPerRack[newRack] = addRegion(regionsPerRack[newRack], region);<a name="line.729"></a>
-<span class="sourceLineNo">730</span>        primariesOfRegionsPerRack[newRack] =<a name="line.730"></a>
-<span class="sourceLineNo">731</span>          addRegionSorted(primariesOfRegionsPerRack[newRack], primary);<a name="line.731"></a>
-<span class="sourceLineNo">732</span>        if (oldRack &gt;= 0) {<a name="line.732"></a>
-<span class="sourceLineNo">733</span>          regionsPerRack[oldRack] = removeRegion(regionsPerRack[oldRack], region);<a name="line.733"></a>
-<span class="sourceLineNo">734</span>          primariesOfRegionsPerRack[oldRack] =<a name="line.734"></a>
-<span class="sourceLineNo">735</span>            removeRegion(primariesOfRegionsPerRack[oldRack], primary); // will still be sorted<a name="line.735"></a>
-<span class="sourceLineNo">736</span>        }<a name="line.736"></a>
-<span class="sourceLineNo">737</span>      }<a name="line.737"></a>
-<span class="sourceLineNo">738</span>    }<a name="line.738"></a>
-<span class="sourceLineNo">739</span>  }<a name="line.739"></a>
-<span class="sourceLineNo">740</span><a name="line.740"></a>
-<span class="sourceLineNo">741</span>  int[] removeRegion(int[] regions, int regionIndex) {<a name="line.741"></a>
-<span class="sourceLineNo">742</span>    // TODO: this maybe costly. Consider using linked lists<a name="line.742"></a>
-<span class="sourceLineNo">743</span>    int[] newRegions = new int[regions.length - 1];<a name="line.743"></a>
-<span class="sourceLineNo">744</span>    int i = 0;<a name="line.744"></a>
-<span class="sourceLineNo">745</span>    for (i = 0; i &lt; regions.length; i++) {<a name="line.745"></a>
-<span class="sourceLineNo">746</span>      if (regions[i] == regionIndex) {<a name="line.746"></a>
-<span class="sourceLineNo">747</span>        break;<a name="line.747"></a>
-<span class="sourceLineNo">748</span>      }<a name="line.748"></a>
-<span class="sourceLineNo">749</span>      newRegions[i] = regions[i];<a name="line.749"></a>
-<span class="sourceLineNo">750</span>    }<a name="line.750"></a>
-<span class="sourceLineNo">751</span>    System.arraycopy(regions, i + 1, newRegions, i, newRegions.length - i);<a name="line.751"></a>
+<span class="sourceLineNo">699</span>    // update for hosts<a name="line.699"></a>
+<span class="sourceLineNo">700</span>    if (multiServersPerHost) {<a name="line.700"></a>
+<span class="sourceLineNo">701</span>      updateForLocation(serverIndexToHostIndex, regionsPerHost, colocatedReplicaCountsPerHost,<a name="line.701"></a>
+<span class="sourceLineNo">702</span>        oldServer, newServer, primary, region);<a name="line.702"></a>
+<span class="sourceLineNo">703</span>    }<a name="line.703"></a>
+<span class="sourceLineNo">704</span><a name="line.704"></a>
+<span class="sourceLineNo">705</span>    // update for racks<a name="line.705"></a>
+<span class="sourceLineNo">706</span>    if (numRacks &gt; 1) {<a name="line.706"></a>
+<span class="sourceLineNo">707</span>      updateForLocation(serverIndexToRackIndex, regionsPerRack, colocatedReplicaCountsPerRack,<a name="line.707"></a>
+<span class="sourceLineNo">708</span>        oldServer, newServer, primary, region);<a name="line.708"></a>
+<span class="sourceLineNo">709</span>    }<a name="line.709"></a>
+<span class="sourceLineNo">710</span>  }<a name="line.710"></a>
+<span class="sourceLineNo">711</span>  /**<a name="line.711"></a>
+<span class="sourceLineNo">712</span>   * Common method for per host and per Location region index updates when a region is moved.<a name="line.712"></a>
+<span class="sourceLineNo">713</span>   * @param serverIndexToLocation serverIndexToHostIndex or serverIndexToLocationIndex<a name="line.713"></a>
+<span class="sourceLineNo">714</span>   * @param regionsPerLocation regionsPerHost or regionsPerLocation<a name="line.714"></a>
+<span class="sourceLineNo">715</span>   * @param colocatedReplicaCountsPerLocation colocatedReplicaCountsPerHost or<a name="line.715"></a>
+<span class="sourceLineNo">716</span>   *                                          colocatedReplicaCountsPerRack<a name="line.716"></a>
+<span class="sourceLineNo">717</span>   */<a name="line.717"></a>
+<span class="sourceLineNo">718</span>  private void updateForLocation(int[] serverIndexToLocation,<a name="line.718"></a>
+<span class="sourceLineNo">719</span>    int[][] regionsPerLocation,<a name="line.719"></a>
+<span class="sourceLineNo">720</span>    Int2IntCounterMap[] colocatedReplicaCountsPerLocation,<a name="line.720"></a>
+<span class="sourceLineNo">721</span>    int oldServer, int newServer, int primary, int region) {<a name="line.721"></a>
+<span class="sourceLineNo">722</span>    int oldLocation = oldServer &gt;= 0 ? serverIndexToLocation[oldServer] : -1;<a name="line.722"></a>
+<span class="sourceLineNo">723</span>    int newLocation = serverIndexToLocation[newServer];<a name="line.723"></a>
+<span class="sourceLineNo">724</span>    if (newLocation != oldLocation) {<a name="line.724"></a>
+<span class="sourceLineNo">725</span>      regionsPerLocation[newLocation] = addRegion(regionsPerLocation[newLocation], region);<a name="line.725"></a>
+<span class="sourceLineNo">726</span>      colocatedReplicaCountsPerLocation[newLocation].getAndIncrement(primary);<a name="line.726"></a>
+<span class="sourceLineNo">727</span>      if (oldLocation &gt;= 0) {<a name="line.727"></a>
+<span class="sourceLineNo">728</span>        regionsPerLocation[oldLocation] = removeRegion(regionsPerLocation[oldLocation], region);<a name="line.728"></a>
+<span class="sourceLineNo">729</span>        colocatedReplicaCountsPerLocation[oldLocation].getAndDecrement(primary);<a name="line.729"></a>
+<span class="sourceLineNo">730</span>      }<a name="line.730"></a>
+<span class="sourceLineNo">731</span>    }<a name="line.731"></a>
+<span class="sourceLineNo">732</span><a name="line.732"></a>
+<span class="sourceLineNo">733</span>  }<a name="line.733"></a>
+<span class="sourceLineNo">734</span>  int[] removeRegion(int[] regions, int regionIndex) {<a name="line.734"></a>
+<span class="sourceLineNo">735</span>    // TODO: this maybe costly. Consider using linked lists<a name="line.735"></a>
+<span class="sourceLineNo">736</span>    int[] newRegions = new int[regions.length - 1];<a name="line.736"></a>
+<span class="sourceLineNo">737</span>    int i = 0;<a name="line.737"></a>
+<span class="sourceLineNo">738</span>    for (i = 0; i &lt; regions.length; i++) {<a name="line.738"></a>
+<span class="sourceLineNo">739</span>      if (regions[i] == regionIndex) {<a name="line.739"></a>
+<span class="sourceLineNo">740</span>        break;<a name="line.740"></a>
+<span class="sourceLineNo">741</span>      }<a name="line.741"></a>
+<span class="sourceLineNo">742</span>      newRegions[i] = regions[i];<a name="line.742"></a>
+<span class="sourceLineNo">743</span>    }<a name="line.743"></a>
+<span class="sourceLineNo">744</span>    System.arraycopy(regions, i + 1, newRegions, i, newRegions.length - i);<a name="line.744"></a>
+<span class="sourceLineNo">745</span>    return newRegions;<a name="line.745"></a>
+<span class="sourceLineNo">746</span>  }<a name="line.746"></a>
+<span class="sourceLineNo">747</span><a name="line.747"></a>
+<span class="sourceLineNo">748</span>  int[] addRegion(int[] regions, int regionIndex) {<a name="line.748"></a>
+<span class="sourceLineNo">749</span>    int[] newRegions = new int[regions.length + 1];<a name="line.749"></a>
+<span class="sourceLineNo">750</span>    System.arraycopy(regions, 0, newRegions, 0, regions.length);<a name="line.750"></a>
+<span class="sourceLineNo">751</span>    newRegions[newRegions.length - 1] = regionIndex;<a name="line.751"></a>
 <span class="sourceLineNo">752</span>    return newRegions;<a name="line.752"></a>
 <span class="sourceLineNo">753</span>  }<a name="line.753"></a>
 <span class="sourceLineNo">754</span><a name="line.754"></a>
-<span class="sourceLineNo">755</span>  int[] addRegion(int[] regions, int regionIndex) {<a name="line.755"></a>
+<span class="sourceLineNo">755</span>  int[] addRegionSorted(int[] regions, int regionIndex) {<a name="line.755"></a>
 <span class="sourceLineNo">756</span>    int[] newRegions = new int[regions.length + 1];<a name="line.756"></a>
-<span class="sourceLineNo">757</span>    System.arraycopy(regions, 0, newRegions, 0, regions.length);<a name="line.757"></a>
-<span class="sourceLineNo">758</span>    newRegions[newRegions.length - 1] = regionIndex;<a name="line.758"></a>
-<span class="sourceLineNo">759</span>    return newRegions;<a name="line.759"></a>
-<span class="sourceLineNo">760</span>  }<a name="line.760"></a>
-<span class="sourceLineNo">761</span><a name="line.761"></a>
-<span class="sourceLineNo">762</span>  int[] addRegionSorted(int[] regions, int regionIndex) {<a name="line.762"></a>
-<span class="sourceLineNo">763</span>    int[] newRegions = new int[regions.length + 1];<a name="line.763"></a>
-<span class="sourceLineNo">764</span>    int i = 0;<a name="line.764"></a>
-<span class="sourceLineNo">765</span>    for (i = 0; i &lt; regions.length; i++) { // find the index to insert<a name="line.765"></a>
-<span class="sourceLineNo">766</span>      if (regions[i] &gt; regionIndex) {<a name="line.766"></a>
-<span class="sourceLineNo">767</span>        break;<a name="line.767"></a>
-<span class="sourceLineNo">768</span>      }<a name="line.768"></a>
-<span class="sourceLineNo">769</span>    }<a name="line.769"></a>
-<span class="sourceLineNo">770</span>    System.arraycopy(regions, 0, newRegions, 0, i); // copy first half<a name="line.770"></a>
-<span class="sourceLineNo">771</span>    System.arraycopy(regions, i, newRegions, i + 1, regions.length - i); // copy second half<a name="line.771"></a>
-<span class="sourceLineNo">772</span>    newRegions[i] = regionIndex;<a name="line.772"></a>
-<span class="sourceLineNo">773</span><a name="line.773"></a>
-<span class="sourceLineNo">774</span>    return newRegions;<a name="line.774"></a>
-<span class="sourceLineNo">775</span>  }<a name="line.775"></a>
-<span class="sourceLineNo">776</span><a name="line.776"></a>
-<span class="sourceLineNo">777</span>  int[] replaceRegion(int[] regions, int regionIndex, int newRegionIndex) {<a name="line.777"></a>
-<span class="sourceLineNo">778</span>    int i = 0;<a name="line.778"></a>
-<span class="sourceLineNo">779</span>    for (i = 0; i &lt; regions.length; i++) {<a name="line.779"></a>
-<span class="sourceLineNo">780</span>      if (regions[i] == regionIndex) {<a name="line.780"></a>
-<span class="sourceLineNo">781</span>        regions[i] = newRegionIndex;<a name="line.781"></a>
-<span class="sourceLineNo">782</span>        break;<a name="line.782"></a>
-<span class="sourceLineNo">783</span>      }<a name="line.783"></a>
-<span class="sourceLineNo">784</span>    }<a name="line.784"></a>
-<span class="sourceLineNo">785</span>    return regions;<a name="line.785"></a>
-<span class="sourceLineNo">786</span>  }<a name="line.786"></a>
-<span class="sourceLineNo">787</span><a name="line.787"></a>
-<span class="sourceLineNo">788</span>  void sortServersByRegionCount() {<a name="line.788"></a>
-<span class="sourceLineNo">789</span>    Arrays.sort(serverIndicesSortedByRegionCount, numRegionsComparator);<a name="line.789"></a>
-<span class="sourceLineNo">790</span>  }<a name="line.790"></a>
-<span class="sourceLineNo">791</span><a name="line.791"></a>
-<span class="sourceLineNo">792</span>  int getNumRegions(int server) {<a name="line.792"></a>
-<span class="sourceLineNo">793</span>    return regionsPerServer[server].length;<a name="line.793"></a>
-<span class="sourceLineNo">794</span>  }<a name="line.794"></a>
-<span class="sourceLineNo">795</span><a name="line.795"></a>
-<span class="sourceLineNo">796</span>  boolean contains(int[] arr, int val) {<a name="line.796"></a>
-<span class="sourceLineNo">797</span>    return Arrays.binarySearch(arr, val) &gt;= 0;<a name="line.797"></a>
-<span class="sourceLineNo">798</span>  }<a name="line.798"></a>
-<span class="sourceLineNo">799</span><a name="line.799"></a>
-<span class="sourceLineNo">800</span>  private Comparator&lt;Integer&gt; numRegionsComparator = Comparator.comparingInt(this::getNumRegions);<a name="line.800"></a>
-<span class="sourceLineNo">801</span><a name="line.801"></a>
-<span class="sourceLineNo">802</span>  int getLowestLocalityRegionOnServer(int serverIndex) {<a name="line.802"></a>
-<span class="sourceLineNo">803</span>    if (regionFinder != null) {<a name="line.803"></a>
-<span class="sourceLineNo">804</span>      float lowestLocality = 1.0f;<a name="line.804"></a>
-<span class="sourceLineNo">805</span>      int lowestLocalityRegionIndex = -1;<a name="line.805"></a>
-<span class="sourceLineNo">806</span>      if (regionsPerServer[serverIndex].length == 0) {<a name="line.806"></a>
-<span class="sourceLineNo">807</span>        // No regions on that region server<a name="line.807"></a>
-<span class="sourceLineNo">808</span>        return -1;<a name="line.808"></a>
-<span class="sourceLineNo">809</span>      }<a name="line.809"></a>
-<span class="sourceLineNo">810</span>      for (int j = 0; j &lt; regionsPerServer[serverIndex].length; j++) {<a name="line.810"></a>
-<span class="sourceLineNo">811</span>        int regionIndex = regionsPerServer[serverIndex][j];<a name="line.811"></a>
-<span class="sourceLineNo">812</span>        HDFSBlocksDistribution distribution =<a name="line.812"></a>
-<span class="sourceLineNo">813</span>          regionFinder.getBlockDistribution(regions[regionIndex]);<a name="line.813"></a>
-<span class="sourceLineNo">814</span>        float locality = distribution.getBlockLocalityIndex(servers[serverIndex].getHostname());<a name="line.814"></a>
-<span class="sourceLineNo">815</span>        // skip empty region<a name="line.815"></a>
-<span class="sourceLineNo">816</span>        if (distribution.getUniqueBlocksTotalWeight() == 0) {<a name="line.816"></a>
-<span class="sourceLineNo">817</span>          continue;<a name="line.817"></a>
-<span class="sourceLineNo">818</span>        }<a name="line.818"></a>
-<span class="sourceLineNo">819</span>        if (locality &lt; lowestLocality) {<a name="line.819"></a>
-<span class="sourceLineNo">820</span>          lowestLocality = locality;<a name="line.820"></a>
-<span class="sourceLineNo">821</span>          lowestLocalityRegionIndex = j;<a name="line.821"></a>
-<span class="sourceLineNo">822</span>        }<a name="line.822"></a>
-<span class="sourceLineNo">823</span>      }<a name="line.823"></a>
-<span class="sourceLineNo">824</span>      if (lowestLocalityRegionIndex == -1) {<a name="line.824"></a>
-<span class="sourceLineNo">825</span>        return -1;<a name="line.825"></a>
+<span class="sourceLineNo">757</span>    int i = 0;<a name="line.757"></a>
+<span class="sourceLineNo">758</span>    for (i = 0; i &lt; regions.length; i++) { // find the index to insert<a name="line.758"></a>
+<span class="sourceLineNo">759</span>      if (regions[i] &gt; regionIndex) {<a name="line.759"></a>
+<span class="sourceLineNo">760</span>        break;<a name="line.760"></a>
+<span class="sourceLineNo">761</span>      }<a name="line.761"></a>
+<span class="sourceLineNo">762</span>    }<a name="line.762"></a>
+<span class="sourceLineNo">763</span>    System.arraycopy(regions, 0, newRegions, 0, i); // copy first half<a name="line.763"></a>
+<span class="sourceLineNo">764</span>    System.arraycopy(regions, i, newRegions, i + 1, regions.length - i); // copy second half<a name="line.764"></a>
+<span class="sourceLineNo">765</span>    newRegions[i] = regionIndex;<a name="line.765"></a>
+<span class="sourceLineNo">766</span><a name="line.766"></a>
+<span class="sourceLineNo">767</span>    return newRegions;<a name="line.767"></a>
+<span class="sourceLineNo">768</span>  }<a name="line.768"></a>
+<span class="sourceLineNo">769</span><a name="line.769"></a>
+<span class="sourceLineNo">770</span>  int[] replaceRegion(int[] regions, int regionIndex, int newRegionIndex) {<a name="line.770"></a>
+<span class="sourceLineNo">771</span>    int i = 0;<a name="line.771"></a>
+<span class="sourceLineNo">772</span>    for (i = 0; i &lt; regions.length; i++) {<a name="line.772"></a>
+<span class="sourceLineNo">773</span>      if (regions[i] == regionIndex) {<a name="line.773"></a>
+<span class="sourceLineNo">774</span>        regions[i] = newRegionIndex;<a name="line.774"></a>
+<span class="sourceLineNo">775</span>        break;<a name="line.775"></a>
+<span class="sourceLineNo">776</span>      }<a name="line.776"></a>
+<span class="sourceLineNo">777</span>    }<a name="line.777"></a>
+<span class="sourceLineNo">778</span>    return regions;<a name="line.778"></a>
+<span class="sourceLineNo">779</span>  }<a name="line.779"></a>
+<span class="sourceLineNo">780</span><a name="line.780"></a>
+<span class="sourceLineNo">781</span>  void sortServersByRegionCount() {<a name="line.781"></a>
+<span class="sourceLineNo">782</span>    Arrays.sort(serverIndicesSortedByRegionCount, numRegionsComparator);<a name="line.782"></a>
+<span class="sourceLineNo">783</span>  }<a name="line.783"></a>
+<span class="sourceLineNo">784</span><a name="line.784"></a>
+<span class="sourceLineNo">785</span>  int getNumRegions(int server) {<a name="line.785"></a>
+<span class="sourceLineNo">786</span>    return regionsPerServer[server].length;<a name="line.786"></a>
+<span class="sourceLineNo">787</span>  }<a name="line.787"></a>
+<span class="sourceLineNo">788</span><a name="line.788"></a>
+<span class="sourceLineNo">789</span>  boolean contains(int[] arr, int val) {<a name="line.789"></a>
+<span class="sourceLineNo">790</span>    return Arrays.binarySearch(arr, val) &gt;= 0;<a name="line.790"></a>
+<span class="sourceLineNo">791</span>  }<a name="line.791"></a>
+<span class="sourceLineNo">792</span><a name="line.792"></a>
+<span class="sourceLineNo">793</span>  private Comparator&lt;Integer&gt; numRegionsComparator = Comparator.comparingInt(this::getNumRegions);<a name="line.793"></a>
+<span class="sourceLineNo">794</span><a name="line.794"></a>
+<span class="sourceLineNo">795</span>  int getLowestLocalityRegionOnServer(int serverIndex) {<a name="line.795"></a>
+<span class="sourceLineNo">796</span>    if (regionFinder != null) {<a name="line.796"></a>
+<span class="sourceLineNo">797</span>      float lowestLocality = 1.0f;<a name="line.797"></a>
+<span class="sourceLineNo">798</span>      int lowestLocalityRegionIndex = -1;<a name="line.798"></a>
+<span class="sourceLineNo">799</span>      if (regionsPerServer[serverIndex].length == 0) {<a name="line.799"></a>
+<span class="sourceLineNo">800</span>        // No regions on that region server<a name="line.800"></a>
+<span class="sourceLineNo">801</span>        return -1;<a name="line.801"></a>
+<span class="sourceLineNo">802</span>      }<a name="line.802"></a>
+<span class="sourceLineNo">803</span>      for (int j = 0; j &lt; regionsPerServer[serverIndex].length; j++) {<a name="line.803"></a>
+<span class="sourceLineNo">804</span>        int regionIndex = regionsPerServer[serverIndex][j];<a name="line.804"></a>
+<span class="sourceLineNo">805</span>        HDFSBlocksDistribution distribution =<a name="line.805"></a>
+<span class="sourceLineNo">806</span>          regionFinder.getBlockDistribution(regions[regionIndex]);<a name="line.806"></a>
+<span class="sourceLineNo">807</span>        float locality = distribution.getBlockLocalityIndex(servers[serverIndex].getHostname());<a name="line.807"></a>
+<span class="sourceLineNo">808</span>        // skip empty region<a name="line.808"></a>
+<span class="sourceLineNo">809</span>        if (distribution.getUniqueBlocksTotalWeight() == 0) {<a name="line.809"></a>
+<span class="sourceLineNo">810</span>          continue;<a name="line.810"></a>
+<span class="sourceLineNo">811</span>        }<a name="line.811"></a>
+<span class="sourceLineNo">812</span>        if (locality &lt; lowestLocality) {<a name="line.812"></a>
+<span class="sourceLineNo">813</span>          lowestLocality = locality;<a name="line.813"></a>
+<span class="sourceLineNo">814</span>          lowestLocalityRegionIndex = j;<a name="line.814"></a>
+<span class="sourceLineNo">815</span>        }<a name="line.815"></a>
+<span class="sourceLineNo">816</span>      }<a name="line.816"></a>
+<span class="sourceLineNo">817</span>      if (lowestLocalityRegionIndex == -1) {<a name="line.817"></a>
+<span class="sourceLineNo">818</span>        return -1;<a name="line.818"></a>
+<span class="sourceLineNo">819</span>      }<a name="line.819"></a>
+<span class="sourceLineNo">820</span>      if (LOG.isTraceEnabled()) {<a name="line.820"></a>
+<span class="sourceLineNo">821</span>        LOG.trace("Lowest locality region is " +<a name="line.821"></a>
+<span class="sourceLineNo">822</span>          regions[regionsPerServer[serverIndex][lowestLocalityRegionIndex]]<a name="line.822"></a>
+<span class="sourceLineNo">823</span>            .getRegionNameAsString() +<a name="line.823"></a>
+<span class="sourceLineNo">824</span>          " with locality " + lowestLocality + " and its region server contains " +<a name="line.824"></a>
+<span class="sourceLineNo">825</span>          regionsPerServer[serverIndex].length + " regions");<a name="line.825"></a>
 <span class="sourceLineNo">826</span>      }<a name="line.826"></a>
-<span class="sourceLineNo">827</span>      if (LOG.isTraceEnabled()) {<a name="line.827"></a>
-<span class="sourceLineNo">828</span>        LOG.trace("Lowest locality region is " +<a name="line.828"></a>
-<span class="sourceLineNo">829</span>          regions[regionsPerServer[serverIndex][lowestLocalityRegionIndex]]<a name="line.829"></a>
-<span class="sourceLineNo">830</span>            .getRegionNameAsString() +<a name="line.830"></a>
-<span class="sourceLineNo">831</span>          " with locality " + lowestLocality + " and its region server contains " +<a name="line.831"></a>
-<span class="sourceLineNo">832</span>          regionsPerServer[serverIndex].length + " regions");<a name="line.832"></a>
-<span class="sourceLineNo">833</span>      }<a name="line.833"></a>
-<span class="sourceLineNo">834</span>      return regionsPerServer[serverIndex][lowestLocalityRegionIndex];<a name="line.834"></a>
-<span class="sourceLineNo">835</span>    } else {<a name="line.835"></a>
-<span class="sourceLineNo">836</span>      return -1;<a name="line.836"></a>
-<span class="sourceLineNo">837</span>    }<a name="line.837"></a>
-<span class="sourceLineNo">838</span>  }<a name="line.838"></a>
-<span class="sourceLineNo">839</span><a name="line.839"></a>
-<span class="sourceLineNo">840</span>  float getLocalityOfRegion(int region, int server) {<a name="line.840"></a>
-<span class="sourceLineNo">841</span>    if (regionFinder != null) {<a name="line.841"></a>
-<span class="sourceLineNo">842</span>      HDFSBlocksDistribution distribution = regionFinder.getBlockDistribution(regions[region]);<a name="line.842"></a>
-<span class="sourceLineNo">843</span>      return distribution.getBlockLocalityIndex(servers[server].getHostname());<a name="line.843"></a>
-<span class="sourceLineNo">844</span>    } else {<a name="line.844"></a>
-<span class="sourceLineNo">845</span>      return 0f;<a name="line.845"></a>
-<span class="sourceLineNo">846</span>    }<a name="line.846"></a>
-<span class="sourceLineNo">847</span>  }<a name="line.847"></a>
-<span class="sourceLineNo">848</span><a name="line.848"></a>
-<span class="sourceLineNo">849</span>  void setNumRegions(int numRegions) {<a name="line.849"></a>
-<span class="sourceLineNo">850</span>    this.numRegions = numRegions;<a name="line.850"></a>
-<span class="sourceLineNo">851</span>  }<a name="line.851"></a>
-<span class="sourceLineNo">852</span><a name="line.852"></a>
-<span class="sourceLineNo">853</span>  void setNumMovedRegions(int numMovedRegions) {<a name="line.853"></a>
-<span class="sourceLineNo">854</span>    this.numMovedRegions = numMovedRegions;<a name="line.854"></a>
-<span class="sourceLineNo">855</span>  }<a name="line.855"></a>
-<span class="sourceLineNo">856</span><a name="line.856"></a>
-<span class="sourceLineNo">857</span>  @Override<a name="line.857"></a>
-<span class="sourceLineNo">858</span>  public String toString() {<a name="line.858"></a>
-<span class="sourceLineNo">859</span>    StringBuilder desc = new StringBuilder("Cluster={servers=[");<a name="line.859"></a>
-<span class="sourceLineNo">860</span>    for (ServerName sn : servers) {<a name="line.860"></a>
-<span class="sourceLineNo">861</span>      desc.append(sn.getAddress().toString()).append(", ");<a name="line.861"></a>
-<span class="sourceLineNo">862</span>    }<a name="line.862"></a>
-<span class="sourceLineNo">863</span>    desc.append("], serverIndicesSortedByRegionCount=")<a name="line.863"></a>
-<span class="sourceLineNo">864</span>      .append(Arrays.toString(serverIndicesSortedByRegionCount)).append(", regionsPerServer=")<a name="line.864"></a>
-<span class="sourceLineNo">865</span>      .append(Arrays.deepToString(regionsPerServer));<a name="line.865"></a>
+<span class="sourceLineNo">827</span>      return regionsPerServer[serverIndex][lowestLocalityRegionIndex];<a name="line.827"></a>
+<span class="sourceLineNo">828</span>    } else {<a name="line.828"></a>
+<span class="sourceLineNo">829</span>      return -1;<a name="line.829"></a>
+<span class="sourceLineNo">830</span>    }<a name="line.830"></a>
+<span class="sourceLineNo">831</span>  }<a name="line.831"></a>
+<span class="sourceLineNo">832</span><a name="line.832"></a>
+<span class="sourceLineNo">833</span>  float getLocalityOfRegion(int region, int server) {<a name="line.833"></a>
+<span class="sourceLineNo">834</span>    if (regionFinder != null) {<a name="line.834"></a>
+<span class="sourceLineNo">835</span>      HDFSBlocksDistribution distribution = regionFinder.getBlockDistribution(regions[region]);<a name="line.835"></a>
+<span class="sourceLineNo">836</span>      return distribution.getBlockLocalityIndex(servers[server].getHostname());<a name="line.836"></a>
+<span class="sourceLineNo">837</span>    } else {<a name="line.837"></a>
+<span class="sourceLineNo">838</span>      return 0f;<a name="line.838"></a>
+<span class="sourceLineNo">839</span>    }<a name="line.839"></a>
+<span class="sourceLineNo">840</span>  }<a name="line.840"></a>
+<span class="sourceLineNo">841</span><a name="line.841"></a>
+<span class="sourceLineNo">842</span>  void setNumRegions(int numRegions) {<a name="line.842"></a>
+<span class="sourceLineNo">843</span>    this.numRegions = numRegions;<a name="line.843"></a>
+<span class="sourceLineNo">844</span>  }<a name="line.844"></a>
+<span class="sourceLineNo">845</span><a name="line.845"></a>
+<span class="sourceLineNo">846</span>  void setNumMovedRegions(int numMovedRegions) {<a name="line.846"></a>
+<span class="sourceLineNo">847</span>    this.numMovedRegions = numMovedRegions;<a name="line.847"></a>
+<span class="sourceLineNo">848</span>  }<a name="line.848"></a>
+<span class="sourceLineNo">849</span><a name="line.849"></a>
+<span class="sourceLineNo">850</span>  @Override<a name="line.850"></a>
+<span class="sourceLineNo">851</span>  public String toString() {<a name="line.851"></a>
+<span class="sourceLineNo">852</span>    StringBuilder desc = new StringBuilder("Cluster={servers=[");<a name="line.852"></a>
+<span class="sourceLineNo">853</span>    for (ServerName sn : servers) {<a name="line.853"></a>
+<span class="sourceLineNo">854</span>      desc.append(sn.getAddress().toString()).append(", ");<a name="line.854"></a>
+<span class="sourceLineNo">855</span>    }<a name="line.855"></a>
+<span class="sourceLineNo">856</span>    desc.append("], serverIndicesSortedByRegionCount=")<a name="line.856"></a>
+<span class="sourceLineNo">857</span>      .append(Arrays.toString(serverIndicesSortedByRegionCount)).append(", regionsPerServer=")<a name="line.857"></a>
+<span class="sourceLineNo">858</span>      .append(Arrays.deepToString(regionsPerServer));<a name="line.858"></a>
+<span class="sourceLineNo">859</span><a name="line.859"></a>
+<span class="sourceLineNo">860</span>    desc.append(", regionSkewByTable=").append(Arrays.toString(regionSkewByTable))<a name="line.860"></a>
+<span class="sourceLineNo">861</span>      .append(", numRegions=").append(numRegions).append(", numServers=").append(numServers)<a name="line.861"></a>
+<span class="sourceLineNo">862</span>      .append(", numTables=").append(numTables).append(", numMovedRegions=").append(numMovedRegions)<a name="line.862"></a>
+<span class="sourceLineNo">863</span>      .append('}');<a name="line.863"></a>
+<span class="sourceLineNo">864</span>    return desc.toString();<a name="line.864"></a>
+<span class="sourceLineNo">865</span>  }<a name="line.865"></a>
 <span class="sourceLineNo">866</span><a name="line.866"></a>
-<span class="sourceLineNo">867</span>    desc.append(", regionSkewByTable=").append(Arrays.toString(regionSkewByTable))<a name="line.867"></a>
-<span class="sourceLineNo">868</span>      .append(", numRegions=").append(numRegions).append(", numServers=").append(numServers)<a name="line.868"></a>
-<span class="sourceLineNo">869</span>      .append(", numTables=").append(numTables).append(", numMovedRegions=").append(numMovedRegions)<a name="line.869"></a>
-<span class="sourceLineNo">870</span>      .append('}');<a name="line.870"></a>
-<span class="sourceLineNo">871</span>    return desc.toString();<a name="line.871"></a>
-<span class="sourceLineNo">872</span>  }<a name="line.872"></a>
-<span class="sourceLineNo">873</span><a name="line.873"></a>
-<span class="sourceLineNo">874</span>  private double getSkewChangeFor(int serverIndex, int tableIndex, int regionCountChange) {<a name="line.874"></a>
-<span class="sourceLineNo">875</span>    double curSkew = Math.abs(numRegionsPerServerPerTable[serverIndex][tableIndex] -<a name="line.875"></a>
-<span class="sourceLineNo">876</span>      meanRegionsPerTable[tableIndex]);<a name="line.876"></a>
-<span class="sourceLineNo">877</span>    double oldSkew = Math.abs(numRegionsPerServerPerTable[serverIndex][tableIndex] -<a name="line.877"></a>
-<span class="sourceLineNo">878</span>      regionCountChange - meanRegionsPerTable[tableIndex]);<a name="line.878"></a>
-<span class="sourceLineNo">879</span>    return curSkew - oldSkew;<a name="line.879"></a>
-<span class="sourceLineNo">880</span>  }<a name="line.880"></a>
-<span class="sourceLineNo">881</span>}<a name="line.881"></a>
+<span class="sourceLineNo">867</span>  private double getSkewChangeFor(int serverIndex, int tableIndex, int regionCountChange) {<a name="line.867"></a>
+<span class="sourceLineNo">868</span>    double curSkew = Math.abs(numRegionsPerServerPerTable[serverIndex][tableIndex] -<a name="line.868"></a>
+<span class="sourceLineNo">869</span>      meanRegionsPerTable[tableIndex]);<a name="line.869"></a>
+<span class="sourceLineNo">870</span>    double oldSkew = Math.abs(numRegionsPerServerPerTable[serverIndex][tableIndex] -<a name="line.870"></a>
+<span class="sourceLineNo">871</span>      regionCountChange - meanRegionsPerTable[tableIndex]);<a name="line.871"></a>
+<span class="sourceLineNo">872</span>    return curSkew - oldSkew;<a name="line.872"></a>
+<span class="sourceLineNo">873</span>  }<a name="line.873"></a>
+<span class="sourceLineNo">874</span>}<a name="line.874"></a>
 
 
 
diff --git a/devapidocs/src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.LocalityType.html b/devapidocs/src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.LocalityType.html
index 71d9218..d15cd10 100644
--- a/devapidocs/src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.LocalityType.html
+++ b/devapidocs/src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.LocalityType.html
@@ -34,859 +34,852 @@
 <span class="sourceLineNo">026</span>import java.util.HashMap;<a name="line.26"></a>
 <span class="sourceLineNo">027</span>import java.util.List;<a name="line.27"></a>
 <span class="sourceLineNo">028</span>import java.util.Map;<a name="line.28"></a>
-<span class="sourceLineNo">029</span>import org.apache.hadoop.hbase.HDFSBlocksDistribution;<a name="line.29"></a>
-<span class="sourceLineNo">030</span>import org.apache.hadoop.hbase.ServerName;<a name="line.30"></a>
-<span class="sourceLineNo">031</span>import org.apache.hadoop.hbase.client.RegionInfo;<a name="line.31"></a>
-<span class="sourceLineNo">032</span>import org.apache.hadoop.hbase.client.RegionReplicaUtil;<a name="line.32"></a>
-<span class="sourceLineNo">033</span>import org.apache.hadoop.hbase.master.RackManager;<a name="line.33"></a>
-<span class="sourceLineNo">034</span>import org.apache.hadoop.hbase.net.Address;<a name="line.34"></a>
-<span class="sourceLineNo">035</span>import org.apache.yetus.audience.InterfaceAudience;<a name="line.35"></a>
-<span class="sourceLineNo">036</span>import org.slf4j.Logger;<a name="line.36"></a>
-<span class="sourceLineNo">037</span>import org.slf4j.LoggerFactory;<a name="line.37"></a>
-<span class="sourceLineNo">038</span><a name="line.38"></a>
-<span class="sourceLineNo">039</span>/**<a name="line.39"></a>
-<span class="sourceLineNo">040</span> * An efficient array based implementation similar to ClusterState for keeping the status of the<a name="line.40"></a>
-<span class="sourceLineNo">041</span> * cluster in terms of region assignment and distribution. LoadBalancers, such as<a name="line.41"></a>
-<span class="sourceLineNo">042</span> * StochasticLoadBalancer uses this Cluster object because of hundreds of thousands of hashmap<a name="line.42"></a>
-<span class="sourceLineNo">043</span> * manipulations are very costly, which is why this class uses mostly indexes and arrays.<a name="line.43"></a>
-<span class="sourceLineNo">044</span> * &lt;p/&gt;<a name="line.44"></a>
-<span class="sourceLineNo">045</span> * BalancerClusterState tracks a list of unassigned regions, region assignments, and the server<a name="line.45"></a>
-<span class="sourceLineNo">046</span> * topology in terms of server names, hostnames and racks.<a name="line.46"></a>
-<span class="sourceLineNo">047</span> */<a name="line.47"></a>
-<span class="sourceLineNo">048</span>@InterfaceAudience.Private<a name="line.48"></a>
-<span class="sourceLineNo">049</span>class BalancerClusterState {<a name="line.49"></a>
-<span class="sourceLineNo">050</span><a name="line.50"></a>
-<span class="sourceLineNo">051</span>  private static final Logger LOG = LoggerFactory.getLogger(BalancerClusterState.class);<a name="line.51"></a>
+<span class="sourceLineNo">029</span>import org.agrona.collections.Hashing;<a name="line.29"></a>
+<span class="sourceLineNo">030</span>import org.agrona.collections.Int2IntCounterMap;<a name="line.30"></a>
+<span class="sourceLineNo">031</span>import org.apache.hadoop.hbase.HDFSBlocksDistribution;<a name="line.31"></a>
+<span class="sourceLineNo">032</span>import org.apache.hadoop.hbase.ServerName;<a name="line.32"></a>
+<span class="sourceLineNo">033</span>import org.apache.hadoop.hbase.client.RegionInfo;<a name="line.33"></a>
+<span class="sourceLineNo">034</span>import org.apache.hadoop.hbase.client.RegionReplicaUtil;<a name="line.34"></a>
+<span class="sourceLineNo">035</span>import org.apache.hadoop.hbase.master.RackManager;<a name="line.35"></a>
+<span class="sourceLineNo">036</span>import org.apache.hadoop.hbase.net.Address;<a name="line.36"></a>
+<span class="sourceLineNo">037</span>import org.apache.yetus.audience.InterfaceAudience;<a name="line.37"></a>
+<span class="sourceLineNo">038</span>import org.slf4j.Logger;<a name="line.38"></a>
+<span class="sourceLineNo">039</span>import org.slf4j.LoggerFactory;<a name="line.39"></a>
+<span class="sourceLineNo">040</span><a name="line.40"></a>
+<span class="sourceLineNo">041</span>/**<a name="line.41"></a>
+<span class="sourceLineNo">042</span> * An efficient array based implementation similar to ClusterState for keeping the status of the<a name="line.42"></a>
+<span class="sourceLineNo">043</span> * cluster in terms of region assignment and distribution. LoadBalancers, such as<a name="line.43"></a>
+<span class="sourceLineNo">044</span> * StochasticLoadBalancer uses this Cluster object because of hundreds of thousands of hashmap<a name="line.44"></a>
+<span class="sourceLineNo">045</span> * manipulations are very costly, which is why this class uses mostly indexes and arrays.<a name="line.45"></a>
+<span class="sourceLineNo">046</span> * &lt;p/&gt;<a name="line.46"></a>
+<span class="sourceLineNo">047</span> * BalancerClusterState tracks a list of unassigned regions, region assignments, and the server<a name="line.47"></a>
+<span class="sourceLineNo">048</span> * topology in terms of server names, hostnames and racks.<a name="line.48"></a>
+<span class="sourceLineNo">049</span> */<a name="line.49"></a>
+<span class="sourceLineNo">050</span>@InterfaceAudience.Private<a name="line.50"></a>
+<span class="sourceLineNo">051</span>class BalancerClusterState {<a name="line.51"></a>
 <span class="sourceLineNo">052</span><a name="line.52"></a>
-<span class="sourceLineNo">053</span>  ServerName[] servers;<a name="line.53"></a>
-<span class="sourceLineNo">054</span>  // ServerName uniquely identifies a region server. multiple RS can run on the same host<a name="line.54"></a>
-<span class="sourceLineNo">055</span>  String[] hosts;<a name="line.55"></a>
-<span class="sourceLineNo">056</span>  String[] racks;<a name="line.56"></a>
-<span class="sourceLineNo">057</span>  boolean multiServersPerHost = false; // whether or not any host has more than one server<a name="line.57"></a>
-<span class="sourceLineNo">058</span><a name="line.58"></a>
-<span class="sourceLineNo">059</span>  ArrayList&lt;String&gt; tables;<a name="line.59"></a>
-<span class="sourceLineNo">060</span>  RegionInfo[] regions;<a name="line.60"></a>
-<span class="sourceLineNo">061</span>  Deque&lt;BalancerRegionLoad&gt;[] regionLoads;<a name="line.61"></a>
-<span class="sourceLineNo">062</span>  private RegionHDFSBlockLocationFinder regionFinder;<a name="line.62"></a>
-<span class="sourceLineNo">063</span><a name="line.63"></a>
-<span class="sourceLineNo">064</span>  int[][] regionLocations; // regionIndex -&gt; list of serverIndex sorted by locality<a name="line.64"></a>
+<span class="sourceLineNo">053</span>  private static final Logger LOG = LoggerFactory.getLogger(BalancerClusterState.class);<a name="line.53"></a>
+<span class="sourceLineNo">054</span><a name="line.54"></a>
+<span class="sourceLineNo">055</span>  ServerName[] servers;<a name="line.55"></a>
+<span class="sourceLineNo">056</span>  // ServerName uniquely identifies a region server. multiple RS can run on the same host<a name="line.56"></a>
+<span class="sourceLineNo">057</span>  String[] hosts;<a name="line.57"></a>
+<span class="sourceLineNo">058</span>  String[] racks;<a name="line.58"></a>
+<span class="sourceLineNo">059</span>  boolean multiServersPerHost = false; // whether or not any host has more than one server<a name="line.59"></a>
+<span class="sourceLineNo">060</span><a name="line.60"></a>
+<span class="sourceLineNo">061</span>  ArrayList&lt;String&gt; tables;<a name="line.61"></a>
+<span class="sourceLineNo">062</span>  RegionInfo[] regions;<a name="line.62"></a>
+<span class="sourceLineNo">063</span>  Deque&lt;BalancerRegionLoad&gt;[] regionLoads;<a name="line.63"></a>
+<span class="sourceLineNo">064</span>  private RegionHDFSBlockLocationFinder regionFinder;<a name="line.64"></a>
 <span class="sourceLineNo">065</span><a name="line.65"></a>
-<span class="sourceLineNo">066</span>  int[] serverIndexToHostIndex; // serverIndex -&gt; host index<a name="line.66"></a>
-<span class="sourceLineNo">067</span>  int[] serverIndexToRackIndex; // serverIndex -&gt; rack index<a name="line.67"></a>
-<span class="sourceLineNo">068</span><a name="line.68"></a>
-<span class="sourceLineNo">069</span>  int[][] regionsPerServer; // serverIndex -&gt; region list<a name="line.69"></a>
-<span class="sourceLineNo">070</span>  int[] serverIndexToRegionsOffset; // serverIndex -&gt; offset of region list<a name="line.70"></a>
-<span class="sourceLineNo">071</span>  int[][] regionsPerHost; // hostIndex -&gt; list of regions<a name="line.71"></a>
-<span class="sourceLineNo">072</span>  int[][] regionsPerRack; // rackIndex -&gt; region list<a name="line.72"></a>
-<span class="sourceLineNo">073</span>  int[][] primariesOfRegionsPerServer; // serverIndex -&gt; sorted list of regions by primary region<a name="line.73"></a>
-<span class="sourceLineNo">074</span>                                       // index<a name="line.74"></a>
-<span class="sourceLineNo">075</span>  int[][] primariesOfRegionsPerHost; // hostIndex -&gt; sorted list of regions by primary region index<a name="line.75"></a>
-<span class="sourceLineNo">076</span>  int[][] primariesOfRegionsPerRack; // rackIndex -&gt; sorted list of regions by primary region index<a name="line.76"></a>
-<span class="sourceLineNo">077</span><a name="line.77"></a>
-<span class="sourceLineNo">078</span>  int[][] serversPerHost; // hostIndex -&gt; list of server indexes<a name="line.78"></a>
-<span class="sourceLineNo">079</span>  int[][] serversPerRack; // rackIndex -&gt; list of server indexes<a name="line.79"></a>
-<span class="sourceLineNo">080</span>  int[] regionIndexToServerIndex; // regionIndex -&gt; serverIndex<a name="line.80"></a>
-<span class="sourceLineNo">081</span>  int[] initialRegionIndexToServerIndex; // regionIndex -&gt; serverIndex (initial cluster state)<a name="line.81"></a>
-<span class="sourceLineNo">082</span>  int[] regionIndexToTableIndex; // regionIndex -&gt; tableIndex<a name="line.82"></a>
-<span class="sourceLineNo">083</span>  int[][] numRegionsPerServerPerTable; // serverIndex -&gt; tableIndex -&gt; # regions<a name="line.83"></a>
-<span class="sourceLineNo">084</span>  int[] numRegionsPerTable; // tableIndex -&gt; region count<a name="line.84"></a>
-<span class="sourceLineNo">085</span>  double[] meanRegionsPerTable; // mean region count per table<a name="line.85"></a>
-<span class="sourceLineNo">086</span>  double[] regionSkewByTable;       // skew on RS per by table<a name="line.86"></a>
-<span class="sourceLineNo">087</span>  double[] minRegionSkewByTable;       // min skew on RS per by table<a name="line.87"></a>
-<span class="sourceLineNo">088</span>  double[] maxRegionSkewByTable;       // max skew on RS per by table<a name="line.88"></a>
-<span class="sourceLineNo">089</span>  int[] regionIndexToPrimaryIndex; // regionIndex -&gt; regionIndex of the primary<a name="line.89"></a>
-<span class="sourceLineNo">090</span>  boolean hasRegionReplicas = false; // whether there is regions with replicas<a name="line.90"></a>
-<span class="sourceLineNo">091</span><a name="line.91"></a>
-<span class="sourceLineNo">092</span>  Integer[] serverIndicesSortedByRegionCount;<a name="line.92"></a>
-<span class="sourceLineNo">093</span>  Integer[] serverIndicesSortedByLocality;<a name="line.93"></a>
-<span class="sourceLineNo">094</span><a name="line.94"></a>
-<span class="sourceLineNo">095</span>  Map&lt;Address, Integer&gt; serversToIndex;<a name="line.95"></a>
-<span class="sourceLineNo">096</span>  Map&lt;String, Integer&gt; hostsToIndex;<a name="line.96"></a>
-<span class="sourceLineNo">097</span>  Map&lt;String, Integer&gt; racksToIndex;<a name="line.97"></a>
-<span class="sourceLineNo">098</span>  Map&lt;String, Integer&gt; tablesToIndex;<a name="line.98"></a>
-<span class="sourceLineNo">099</span>  Map&lt;RegionInfo, Integer&gt; regionsToIndex;<a name="line.99"></a>
-<span class="sourceLineNo">100</span>  float[] localityPerServer;<a name="line.100"></a>
-<span class="sourceLineNo">101</span><a name="line.101"></a>
-<span class="sourceLineNo">102</span>  int numServers;<a name="line.102"></a>
-<span class="sourceLineNo">103</span>  int numHosts;<a name="line.103"></a>
-<span class="sourceLineNo">104</span>  int numRacks;<a name="line.104"></a>
-<span class="sourceLineNo">105</span>  int numTables;<a name="line.105"></a>
-<span class="sourceLineNo">106</span>  int numRegions;<a name="line.106"></a>
-<span class="sourceLineNo">107</span><a name="line.107"></a>
-<span class="sourceLineNo">108</span>  int numMovedRegions = 0; // num moved regions from the initial configuration<a name="line.108"></a>
-<span class="sourceLineNo">109</span>  Map&lt;ServerName, List&lt;RegionInfo&gt;&gt; clusterState;<a name="line.109"></a>
-<span class="sourceLineNo">110</span><a name="line.110"></a>
-<span class="sourceLineNo">111</span>  private final RackManager rackManager;<a name="line.111"></a>
-<span class="sourceLineNo">112</span>  // Maps region -&gt; rackIndex -&gt; locality of region on rack<a name="line.112"></a>
-<span class="sourceLineNo">113</span>  private float[][] rackLocalities;<a name="line.113"></a>
-<span class="sourceLineNo">114</span>  // Maps localityType -&gt; region -&gt; [server|rack]Index with highest locality<a name="line.114"></a>
-<span class="sourceLineNo">115</span>  private int[][] regionsToMostLocalEntities;<a name="line.115"></a>
-<span class="sourceLineNo">116</span><a name="line.116"></a>
-<span class="sourceLineNo">117</span>  static class DefaultRackManager extends RackManager {<a name="line.117"></a>
-<span class="sourceLineNo">118</span>    @Override<a name="line.118"></a>
-<span class="sourceLineNo">119</span>    public String getRack(ServerName server) {<a name="line.119"></a>
-<span class="sourceLineNo">120</span>      return UNKNOWN_RACK;<a name="line.120"></a>
-<span class="sourceLineNo">121</span>    }<a name="line.121"></a>
-<span class="sourceLineNo">122</span>  }<a name="line.122"></a>
-<span class="sourceLineNo">123</span><a name="line.123"></a>
-<span class="sourceLineNo">124</span>  BalancerClusterState(Map&lt;ServerName, List&lt;RegionInfo&gt;&gt; clusterState,<a name="line.124"></a>
-<span class="sourceLineNo">125</span>    Map&lt;String, Deque&lt;BalancerRegionLoad&gt;&gt; loads, RegionHDFSBlockLocationFinder regionFinder,<a name="line.125"></a>
-<span class="sourceLineNo">126</span>    RackManager rackManager) {<a name="line.126"></a>
-<span class="sourceLineNo">127</span>    this(null, clusterState, loads, regionFinder, rackManager);<a name="line.127"></a>
-<span class="sourceLineNo">128</span>  }<a name="line.128"></a>
-<span class="sourceLineNo">129</span><a name="line.129"></a>
-<span class="sourceLineNo">130</span>  @SuppressWarnings("unchecked")<a name="line.130"></a>
-<span class="sourceLineNo">131</span>  BalancerClusterState(Collection&lt;RegionInfo&gt; unassignedRegions,<a name="line.131"></a>
-<span class="sourceLineNo">132</span>    Map&lt;ServerName, List&lt;RegionInfo&gt;&gt; clusterState, Map&lt;String, Deque&lt;BalancerRegionLoad&gt;&gt; loads,<a name="line.132"></a>
-<span class="sourceLineNo">133</span>    RegionHDFSBlockLocationFinder regionFinder, RackManager rackManager) {<a name="line.133"></a>
-<span class="sourceLineNo">134</span>    if (unassignedRegions == null) {<a name="line.134"></a>
-<span class="sourceLineNo">135</span>      unassignedRegions = Collections.emptyList();<a name="line.135"></a>
-<span class="sourceLineNo">136</span>    }<a name="line.136"></a>
-<span class="sourceLineNo">137</span><a name="line.137"></a>
-<span class="sourceLineNo">138</span>    serversToIndex = new HashMap&lt;&gt;();<a name="line.138"></a>
-<span class="sourceLineNo">139</span>    hostsToIndex = new HashMap&lt;&gt;();<a name="line.139"></a>
-<span class="sourceLineNo">140</span>    racksToIndex = new HashMap&lt;&gt;();<a name="line.140"></a>
-<span class="sourceLineNo">141</span>    tablesToIndex = new HashMap&lt;&gt;();<a name="line.141"></a>
-<span class="sourceLineNo">142</span><a name="line.142"></a>
-<span class="sourceLineNo">143</span>    // TODO: We should get the list of tables from master<a name="line.143"></a>
-<span class="sourceLineNo">144</span>    tables = new ArrayList&lt;&gt;();<a name="line.144"></a>
-<span class="sourceLineNo">145</span>    this.rackManager = rackManager != null ? rackManager : new DefaultRackManager();<a name="line.145"></a>
+<span class="sourceLineNo">066</span>  int[][] regionLocations; // regionIndex -&gt; list of serverIndex sorted by locality<a name="line.66"></a>
+<span class="sourceLineNo">067</span><a name="line.67"></a>
+<span class="sourceLineNo">068</span>  int[] serverIndexToHostIndex; // serverIndex -&gt; host index<a name="line.68"></a>
+<span class="sourceLineNo">069</span>  int[] serverIndexToRackIndex; // serverIndex -&gt; rack index<a name="line.69"></a>
+<span class="sourceLineNo">070</span><a name="line.70"></a>
+<span class="sourceLineNo">071</span>  int[][] regionsPerServer; // serverIndex -&gt; region list<a name="line.71"></a>
+<span class="sourceLineNo">072</span>  int[] serverIndexToRegionsOffset; // serverIndex -&gt; offset of region list<a name="line.72"></a>
+<span class="sourceLineNo">073</span>  int[][] regionsPerHost; // hostIndex -&gt; list of regions<a name="line.73"></a>
+<span class="sourceLineNo">074</span>  int[][] regionsPerRack; // rackIndex -&gt; region list<a name="line.74"></a>
+<span class="sourceLineNo">075</span>  Int2IntCounterMap[] colocatedReplicaCountsPerServer; // serverIndex -&gt; counts of colocated<a name="line.75"></a>
+<span class="sourceLineNo">076</span>                                       // replicas by primary region index<a name="line.76"></a>
+<span class="sourceLineNo">077</span>  Int2IntCounterMap[] colocatedReplicaCountsPerHost; // hostIndex -&gt; counts of colocated replicas by<a name="line.77"></a>
+<span class="sourceLineNo">078</span>                                      // primary region index<a name="line.78"></a>
+<span class="sourceLineNo">079</span>  Int2IntCounterMap[] colocatedReplicaCountsPerRack; // rackIndex -&gt; counts of colocated replicas by<a name="line.79"></a>
+<span class="sourceLineNo">080</span>                                      // primary region index<a name="line.80"></a>
+<span class="sourceLineNo">081</span><a name="line.81"></a>
+<span class="sourceLineNo">082</span>  int[][] serversPerHost; // hostIndex -&gt; list of server indexes<a name="line.82"></a>
+<span class="sourceLineNo">083</span>  int[][] serversPerRack; // rackIndex -&gt; list of server indexes<a name="line.83"></a>
+<span class="sourceLineNo">084</span>  int[] regionIndexToServerIndex; // regionIndex -&gt; serverIndex<a name="line.84"></a>
+<span class="sourceLineNo">085</span>  int[] initialRegionIndexToServerIndex; // regionIndex -&gt; serverIndex (initial cluster state)<a name="line.85"></a>
+<span class="sourceLineNo">086</span>  int[] regionIndexToTableIndex; // regionIndex -&gt; tableIndex<a name="line.86"></a>
+<span class="sourceLineNo">087</span>  int[][] numRegionsPerServerPerTable; // serverIndex -&gt; tableIndex -&gt; # regions<a name="line.87"></a>
+<span class="sourceLineNo">088</span>  int[] numRegionsPerTable; // tableIndex -&gt; region count<a name="line.88"></a>
+<span class="sourceLineNo">089</span>  double[] meanRegionsPerTable; // mean region count per table<a name="line.89"></a>
+<span class="sourceLineNo">090</span>  double[] regionSkewByTable;       // skew on RS per by table<a name="line.90"></a>
+<span class="sourceLineNo">091</span>  double[] minRegionSkewByTable;       // min skew on RS per by table<a name="line.91"></a>
+<span class="sourceLineNo">092</span>  double[] maxRegionSkewByTable;       // max skew on RS per by table<a name="line.92"></a>
+<span class="sourceLineNo">093</span>  int[] regionIndexToPrimaryIndex; // regionIndex -&gt; regionIndex of the primary<a name="line.93"></a>
+<span class="sourceLineNo">094</span>  boolean hasRegionReplicas = false; // whether there is regions with replicas<a name="line.94"></a>
+<span class="sourceLineNo">095</span><a name="line.95"></a>
+<span class="sourceLineNo">096</span>  Integer[] serverIndicesSortedByRegionCount;<a name="line.96"></a>
+<span class="sourceLineNo">097</span>  Integer[] serverIndicesSortedByLocality;<a name="line.97"></a>
+<span class="sourceLineNo">098</span><a name="line.98"></a>
+<span class="sourceLineNo">099</span>  Map&lt;Address, Integer&gt; serversToIndex;<a name="line.99"></a>
+<span class="sourceLineNo">100</span>  Map&lt;String, Integer&gt; hostsToIndex;<a name="line.100"></a>
+<span class="sourceLineNo">101</span>  Map&lt;String, Integer&gt; racksToIndex;<a name="line.101"></a>
+<span class="sourceLineNo">102</span>  Map&lt;String, Integer&gt; tablesToIndex;<a name="line.102"></a>
+<span class="sourceLineNo">103</span>  Map&lt;RegionInfo, Integer&gt; regionsToIndex;<a name="line.103"></a>
+<span class="sourceLineNo">104</span>  float[] localityPerServer;<a name="line.104"></a>
+<span class="sourceLineNo">105</span><a name="line.105"></a>
+<span class="sourceLineNo">106</span>  int numServers;<a name="line.106"></a>
+<span class="sourceLineNo">107</span>  int numHosts;<a name="line.107"></a>
+<span class="sourceLineNo">108</span>  int numRacks;<a name="line.108"></a>
+<span class="sourceLineNo">109</span>  int numTables;<a name="line.109"></a>
+<span class="sourceLineNo">110</span>  int numRegions;<a name="line.110"></a>
+<span class="sourceLineNo">111</span><a name="line.111"></a>
+<span class="sourceLineNo">112</span>  int numMovedRegions = 0; // num moved regions from the initial configuration<a name="line.112"></a>
+<span class="sourceLineNo">113</span>  Map&lt;ServerName, List&lt;RegionInfo&gt;&gt; clusterState;<a name="line.113"></a>
+<span class="sourceLineNo">114</span><a name="line.114"></a>
+<span class="sourceLineNo">115</span>  private final RackManager rackManager;<a name="line.115"></a>
+<span class="sourceLineNo">116</span>  // Maps region -&gt; rackIndex -&gt; locality of region on rack<a name="line.116"></a>
+<span class="sourceLineNo">117</span>  private float[][] rackLocalities;<a name="line.117"></a>
+<span class="sourceLineNo">118</span>  // Maps localityType -&gt; region -&gt; [server|rack]Index with highest locality<a name="line.118"></a>
+<span class="sourceLineNo">119</span>  private int[][] regionsToMostLocalEntities;<a name="line.119"></a>
+<span class="sourceLineNo">120</span><a name="line.120"></a>
+<span class="sourceLineNo">121</span>  static class DefaultRackManager extends RackManager {<a name="line.121"></a>
+<span class="sourceLineNo">122</span>    @Override<a name="line.122"></a>
+<span class="sourceLineNo">123</span>    public String getRack(ServerName server) {<a name="line.123"></a>
+<span class="sourceLineNo">124</span>      return UNKNOWN_RACK;<a name="line.124"></a>
+<span class="sourceLineNo">125</span>    }<a name="line.125"></a>
+<span class="sourceLineNo">126</span>  }<a name="line.126"></a>
+<span class="sourceLineNo">127</span><a name="line.127"></a>
+<span class="sourceLineNo">128</span>  BalancerClusterState(Map&lt;ServerName, List&lt;RegionInfo&gt;&gt; clusterState,<a name="line.128"></a>
+<span class="sourceLineNo">129</span>    Map&lt;String, Deque&lt;BalancerRegionLoad&gt;&gt; loads, RegionHDFSBlockLocationFinder regionFinder,<a name="line.129"></a>
+<span class="sourceLineNo">130</span>    RackManager rackManager) {<a name="line.130"></a>
+<span class="sourceLineNo">131</span>    this(null, clusterState, loads, regionFinder, rackManager);<a name="line.131"></a>
+<span class="sourceLineNo">132</span>  }<a name="line.132"></a>
+<span class="sourceLineNo">133</span><a name="line.133"></a>
+<span class="sourceLineNo">134</span>  @SuppressWarnings("unchecked")<a name="line.134"></a>
+<span class="sourceLineNo">135</span>  BalancerClusterState(Collection&lt;RegionInfo&gt; unassignedRegions,<a name="line.135"></a>
+<span class="sourceLineNo">136</span>    Map&lt;ServerName, List&lt;RegionInfo&gt;&gt; clusterState, Map&lt;String, Deque&lt;BalancerRegionLoad&gt;&gt; loads,<a name="line.136"></a>
+<span class="sourceLineNo">137</span>    RegionHDFSBlockLocationFinder regionFinder, RackManager rackManager) {<a name="line.137"></a>
+<span class="sourceLineNo">138</span>    if (unassignedRegions == null) {<a name="line.138"></a>
+<span class="sourceLineNo">139</span>      unassignedRegions = Collections.emptyList();<a name="line.139"></a>
+<span class="sourceLineNo">140</span>    }<a name="line.140"></a>
+<span class="sourceLineNo">141</span><a name="line.141"></a>
+<span class="sourceLineNo">142</span>    serversToIndex = new HashMap&lt;&gt;();<a name="line.142"></a>
+<span class="sourceLineNo">143</span>    hostsToIndex = new HashMap&lt;&gt;();<a name="line.143"></a>
+<span class="sourceLineNo">144</span>    racksToIndex = new HashMap&lt;&gt;();<a name="line.144"></a>
+<span class="sourceLineNo">145</span>    tablesToIndex = new HashMap&lt;&gt;();<a name="line.145"></a>
 <span class="sourceLineNo">146</span><a name="line.146"></a>
-<span class="sourceLineNo">147</span>    numRegions = 0;<a name="line.147"></a>
-<span class="sourceLineNo">148</span><a name="line.148"></a>
-<span class="sourceLineNo">149</span>    List&lt;List&lt;Integer&gt;&gt; serversPerHostList = new ArrayList&lt;&gt;();<a name="line.149"></a>
-<span class="sourceLineNo">150</span>    List&lt;List&lt;Integer&gt;&gt; serversPerRackList = new ArrayList&lt;&gt;();<a name="line.150"></a>
-<span class="sourceLineNo">151</span>    this.clusterState = clusterState;<a name="line.151"></a>
-<span class="sourceLineNo">152</span>    this.regionFinder = regionFinder;<a name="line.152"></a>
-<span class="sourceLineNo">153</span><a name="line.153"></a>
-<span class="sourceLineNo">154</span>    // Use servername and port as there can be dead servers in this list. We want everything with<a name="line.154"></a>
-<span class="sourceLineNo">155</span>    // a matching hostname and port to have the same index.<a name="line.155"></a>
-<span class="sourceLineNo">156</span>    for (ServerName sn : clusterState.keySet()) {<a name="line.156"></a>
-<span class="sourceLineNo">157</span>      if (sn == null) {<a name="line.157"></a>
-<span class="sourceLineNo">158</span>        LOG.warn("TODO: Enable TRACE on BaseLoadBalancer. Empty servername); " +<a name="line.158"></a>
-<span class="sourceLineNo">159</span>          "skipping; unassigned regions?");<a name="line.159"></a>
-<span class="sourceLineNo">160</span>        if (LOG.isTraceEnabled()) {<a name="line.160"></a>
-<span class="sourceLineNo">161</span>          LOG.trace("EMPTY SERVERNAME " + clusterState.toString());<a name="line.161"></a>
-<span class="sourceLineNo">162</span>        }<a name="line.162"></a>
-<span class="sourceLineNo">163</span>        continue;<a name="line.163"></a>
-<span class="sourceLineNo">164</span>      }<a name="line.164"></a>
-<span class="sourceLineNo">165</span>      if (serversToIndex.get(sn.getAddress()) == null) {<a name="line.165"></a>
-<span class="sourceLineNo">166</span>        serversToIndex.put(sn.getAddress(), numServers++);<a name="line.166"></a>
-<span class="sourceLineNo">167</span>      }<a name="line.167"></a>
-<span class="sourceLineNo">168</span>      if (!hostsToIndex.containsKey(sn.getHostname())) {<a name="line.168"></a>
-<span class="sourceLineNo">169</span>        hostsToIndex.put(sn.getHostname(), numHosts++);<a name="line.169"></a>
-<span class="sourceLineNo">170</span>        serversPerHostList.add(new ArrayList&lt;&gt;(1));<a name="line.170"></a>
+<span class="sourceLineNo">147</span>    // TODO: We should get the list of tables from master<a name="line.147"></a>
+<span class="sourceLineNo">148</span>    tables = new ArrayList&lt;&gt;();<a name="line.148"></a>
+<span class="sourceLineNo">149</span>    this.rackManager = rackManager != null ? rackManager : new DefaultRackManager();<a name="line.149"></a>
+<span class="sourceLineNo">150</span><a name="line.150"></a>
+<span class="sourceLineNo">151</span>    numRegions = 0;<a name="line.151"></a>
+<span class="sourceLineNo">152</span><a name="line.152"></a>
+<span class="sourceLineNo">153</span>    List&lt;List&lt;Integer&gt;&gt; serversPerHostList = new ArrayList&lt;&gt;();<a name="line.153"></a>
+<span class="sourceLineNo">154</span>    List&lt;List&lt;Integer&gt;&gt; serversPerRackList = new ArrayList&lt;&gt;();<a name="line.154"></a>
+<span class="sourceLineNo">155</span>    this.clusterState = clusterState;<a name="line.155"></a>
+<span class="sourceLineNo">156</span>    this.regionFinder = regionFinder;<a name="line.156"></a>
+<span class="sourceLineNo">157</span><a name="line.157"></a>
+<span class="sourceLineNo">158</span>    // Use servername and port as there can be dead servers in this list. We want everything with<a name="line.158"></a>
+<span class="sourceLineNo">159</span>    // a matching hostname and port to have the same index.<a name="line.159"></a>
+<span class="sourceLineNo">160</span>    for (ServerName sn : clusterState.keySet()) {<a name="line.160"></a>
+<span class="sourceLineNo">161</span>      if (sn == null) {<a name="line.161"></a>
+<span class="sourceLineNo">162</span>        LOG.warn("TODO: Enable TRACE on BaseLoadBalancer. Empty servername); " +<a name="line.162"></a>
+<span class="sourceLineNo">163</span>          "skipping; unassigned regions?");<a name="line.163"></a>
+<span class="sourceLineNo">164</span>        if (LOG.isTraceEnabled()) {<a name="line.164"></a>
+<span class="sourceLineNo">165</span>          LOG.trace("EMPTY SERVERNAME " + clusterState.toString());<a name="line.165"></a>
+<span class="sourceLineNo">166</span>        }<a name="line.166"></a>
+<span class="sourceLineNo">167</span>        continue;<a name="line.167"></a>
+<span class="sourceLineNo">168</span>      }<a name="line.168"></a>
+<span class="sourceLineNo">169</span>      if (serversToIndex.get(sn.getAddress()) == null) {<a name="line.169"></a>
+<span class="sourceLineNo">170</span>        serversToIndex.put(sn.getAddress(), numServers++);<a name="line.170"></a>
 <span class="sourceLineNo">171</span>      }<a name="line.171"></a>
-<span class="sourceLineNo">172</span><a name="line.172"></a>
-<span class="sourceLineNo">173</span>      int serverIndex = serversToIndex.get(sn.getAddress());<a name="line.173"></a>
-<span class="sourceLineNo">174</span>      int hostIndex = hostsToIndex.get(sn.getHostname());<a name="line.174"></a>
-<span class="sourceLineNo">175</span>      serversPerHostList.get(hostIndex).add(serverIndex);<a name="line.175"></a>
+<span class="sourceLineNo">172</span>      if (!hostsToIndex.containsKey(sn.getHostname())) {<a name="line.172"></a>
+<span class="sourceLineNo">173</span>        hostsToIndex.put(sn.getHostname(), numHosts++);<a name="line.173"></a>
+<span class="sourceLineNo">174</span>        serversPerHostList.add(new ArrayList&lt;&gt;(1));<a name="line.174"></a>
+<span class="sourceLineNo">175</span>      }<a name="line.175"></a>
 <span class="sourceLineNo">176</span><a name="line.176"></a>
-<span class="sourceLineNo">177</span>      String rack = this.rackManager.getRack(sn);<a name="line.177"></a>
-<span class="sourceLineNo">178</span>      if (!racksToIndex.containsKey(rack)) {<a name="line.178"></a>
-<span class="sourceLineNo">179</span>        racksToIndex.put(rack, numRacks++);<a name="line.179"></a>
-<span class="sourceLineNo">180</span>        serversPerRackList.add(new ArrayList&lt;&gt;());<a name="line.180"></a>
-<span class="sourceLineNo">181</span>      }<a name="line.181"></a>
-<span class="sourceLineNo">182</span>      int rackIndex = racksToIndex.get(rack);<a name="line.182"></a>
-<span class="sourceLineNo">183</span>      serversPerRackList.get(rackIndex).add(serverIndex);<a name="line.183"></a>
-<span class="sourceLineNo">184</span>    }<a name="line.184"></a>
-<span class="sourceLineNo">185</span><a name="line.185"></a>
-<span class="sourceLineNo">186</span>    // Count how many regions there are.<a name="line.186"></a>
-<span class="sourceLineNo">187</span>    for (Map.Entry&lt;ServerName, List&lt;RegionInfo&gt;&gt; entry : clusterState.entrySet()) {<a name="line.187"></a>
-<span class="sourceLineNo">188</span>      numRegions += entry.getValue().size();<a name="line.188"></a>
-<span class="sourceLineNo">189</span>    }<a name="line.189"></a>
-<span class="sourceLineNo">190</span>    numRegions += unassignedRegions.size();<a name="line.190"></a>
-<span class="sourceLineNo">191</span><a name="line.191"></a>
-<span class="sourceLineNo">192</span>    regionsToIndex = new HashMap&lt;&gt;(numRegions);<a name="line.192"></a>
-<span class="sourceLineNo">193</span>    servers = new ServerName[numServers];<a name="line.193"></a>
-<span class="sourceLineNo">194</span>    serversPerHost = new int[numHosts][];<a name="line.194"></a>
-<span class="sourceLineNo">195</span>    serversPerRack = new int[numRacks][];<a name="line.195"></a>
-<span class="sourceLineNo">196</span>    regions = new RegionInfo[numRegions];<a name="line.196"></a>
-<span class="sourceLineNo">197</span>    regionIndexToServerIndex = new int[numRegions];<a name="line.197"></a>
-<span class="sourceLineNo">198</span>    initialRegionIndexToServerIndex = new int[numRegions];<a name="line.198"></a>
-<span class="sourceLineNo">199</span>    regionIndexToTableIndex = new int[numRegions];<a name="line.199"></a>
-<span class="sourceLineNo">200</span>    regionIndexToPrimaryIndex = new int[numRegions];<a name="line.200"></a>
-<span class="sourceLineNo">201</span>    regionLoads = new Deque[numRegions];<a name="line.201"></a>
-<span class="sourceLineNo">202</span><a name="line.202"></a>
-<span class="sourceLineNo">203</span>    regionLocations = new int[numRegions][];<a name="line.203"></a>
-<span class="sourceLineNo">204</span>    serverIndicesSortedByRegionCount = new Integer[numServers];<a name="line.204"></a>
-<span class="sourceLineNo">205</span>    serverIndicesSortedByLocality = new Integer[numServers];<a name="line.205"></a>
-<span class="sourceLineNo">206</span>    localityPerServer = new float[numServers];<a name="line.206"></a>
-<span class="sourceLineNo">207</span><a name="line.207"></a>
-<span class="sourceLineNo">208</span>    serverIndexToHostIndex = new int[numServers];<a name="line.208"></a>
-<span class="sourceLineNo">209</span>    serverIndexToRackIndex = new int[numServers];<a name="line.209"></a>
-<span class="sourceLineNo">210</span>    regionsPerServer = new int[numServers][];<a name="line.210"></a>
-<span class="sourceLineNo">211</span>    serverIndexToRegionsOffset = new int[numServers];<a name="line.211"></a>
-<span class="sourceLineNo">212</span>    regionsPerHost = new int[numHosts][];<a name="line.212"></a>
-<span class="sourceLineNo">213</span>    regionsPerRack = new int[numRacks][];<a name="line.213"></a>
-<span class="sourceLineNo">214</span>    primariesOfRegionsPerServer = new int[numServers][];<a name="line.214"></a>
-<span class="sourceLineNo">215</span>    primariesOfRegionsPerHost = new int[numHosts][];<a name="line.215"></a>
-<span class="sourceLineNo">216</span>    primariesOfRegionsPerRack = new int[numRacks][];<a name="line.216"></a>
-<span class="sourceLineNo">217</span><a name="line.217"></a>
-<span class="sourceLineNo">218</span>    int tableIndex = 0, regionIndex = 0, regionPerServerIndex = 0;<a name="line.218"></a>
-<span class="sourceLineNo">219</span><a name="line.219"></a>
-<span class="sourceLineNo">220</span>    for (Map.Entry&lt;ServerName, List&lt;RegionInfo&gt;&gt; entry : clusterState.entrySet()) {<a name="line.220"></a>
-<span class="sourceLineNo">221</span>      if (entry.getKey() == null) {<a name="line.221"></a>
-<span class="sourceLineNo">222</span>        LOG.warn("SERVERNAME IS NULL, skipping " + entry.getValue());<a name="line.222"></a>
-<span class="sourceLineNo">223</span>        continue;<a name="line.223"></a>
-<span class="sourceLineNo">224</span>      }<a name="line.224"></a>
-<span class="sourceLineNo">225</span>      int serverIndex = serversToIndex.get(entry.getKey().getAddress());<a name="line.225"></a>
-<span class="sourceLineNo">226</span><a name="line.226"></a>
-<span class="sourceLineNo">227</span>      // keep the servername if this is the first server name for this hostname<a name="line.227"></a>
-<span class="sourceLineNo">228</span>      // or this servername has the newest startcode.<a name="line.228"></a>
-<span class="sourceLineNo">229</span>      if (servers[serverIndex] == null ||<a name="line.229"></a>
-<span class="sourceLineNo">230</span>        servers[serverIndex].getStartcode() &lt; entry.getKey().getStartcode()) {<a name="line.230"></a>
-<span class="sourceLineNo">231</span>        servers[serverIndex] = entry.getKey();<a name="line.231"></a>
-<span class="sourceLineNo">232</span>      }<a name="line.232"></a>
-<span class="sourceLineNo">233</span><a name="line.233"></a>
-<span class="sourceLineNo">234</span>      if (regionsPerServer[serverIndex] != null) {<a name="line.234"></a>
-<span class="sourceLineNo">235</span>        // there is another server with the same hostAndPort in ClusterState.<a name="line.235"></a>
-<span class="sourceLineNo">236</span>        // allocate the array for the total size<a name="line.236"></a>
-<span class="sourceLineNo">237</span>        regionsPerServer[serverIndex] =<a name="line.237"></a>
-<span class="sourceLineNo">238</span>          new int[entry.getValue().size() + regionsPerServer[serverIndex].length];<a name="line.238"></a>
-<span class="sourceLineNo">239</span>      } else {<a name="line.239"></a>
-<span class="sourceLineNo">240</span>        regionsPerServer[serverIndex] = new int[entry.getValue().size()];<a name="line.240"></a>
-<span class="sourceLineNo">241</span>      }<a name="line.241"></a>
-<span class="sourceLineNo">242</span>      primariesOfRegionsPerServer[serverIndex] = new int[regionsPerServer[serverIndex].length];<a name="line.242"></a>
-<span class="sourceLineNo">243</span>      serverIndicesSortedByRegionCount[serverIndex] = serverIndex;<a name="line.243"></a>
-<span class="sourceLineNo">244</span>      serverIndicesSortedByLocality[serverIndex] = serverIndex;<a name="line.244"></a>
-<span class="sourceLineNo">245</span>    }<a name="line.245"></a>
-<span class="sourceLineNo">246</span><a name="line.246"></a>
-<span class="sourceLineNo">247</span>    hosts = new String[numHosts];<a name="line.247"></a>
-<span class="sourceLineNo">248</span>    for (Map.Entry&lt;String, Integer&gt; entry : hostsToIndex.entrySet()) {<a name="line.248"></a>
-<span class="sourceLineNo">249</span>      hosts[entry.getValue()] = entry.getKey();<a name="line.249"></a>
+<span class="sourceLineNo">177</span>      int serverIndex = serversToIndex.get(sn.getAddress());<a name="line.177"></a>
+<span class="sourceLineNo">178</span>      int hostIndex = hostsToIndex.get(sn.getHostname());<a name="line.178"></a>
+<span class="sourceLineNo">179</span>      serversPerHostList.get(hostIndex).add(serverIndex);<a name="line.179"></a>
+<span class="sourceLineNo">180</span><a name="line.180"></a>
+<span class="sourceLineNo">181</span>      String rack = this.rackManager.getRack(sn);<a name="line.181"></a>
+<span class="sourceLineNo">182</span>      if (!racksToIndex.containsKey(rack)) {<a name="line.182"></a>
+<span class="sourceLineNo">183</span>        racksToIndex.put(rack, numRacks++);<a name="line.183"></a>
+<span class="sourceLineNo">184</span>        serversPerRackList.add(new ArrayList&lt;&gt;());<a name="line.184"></a>
+<span class="sourceLineNo">185</span>      }<a name="line.185"></a>
+<span class="sourceLineNo">186</span>      int rackIndex = racksToIndex.get(rack);<a name="line.186"></a>
+<span class="sourceLineNo">187</span>      serversPerRackList.get(rackIndex).add(serverIndex);<a name="line.187"></a>
+<span class="sourceLineNo">188</span>    }<a name="line.188"></a>
+<span class="sourceLineNo">189</span><a name="line.189"></a>
+<span class="sourceLineNo">190</span>    // Count how many regions there are.<a name="line.190"></a>
+<span class="sourceLineNo">191</span>    for (Map.Entry&lt;ServerName, List&lt;RegionInfo&gt;&gt; entry : clusterState.entrySet()) {<a name="line.191"></a>
+<span class="sourceLineNo">192</span>      numRegions += entry.getValue().size();<a name="line.192"></a>
+<span class="sourceLineNo">193</span>    }<a name="line.193"></a>
+<span class="sourceLineNo">194</span>    numRegions += unassignedRegions.size();<a name="line.194"></a>
+<span class="sourceLineNo">195</span><a name="line.195"></a>
+<span class="sourceLineNo">196</span>    regionsToIndex = new HashMap&lt;&gt;(numRegions);<a name="line.196"></a>
+<span class="sourceLineNo">197</span>    servers = new ServerName[numServers];<a name="line.197"></a>
+<span class="sourceLineNo">198</span>    serversPerHost = new int[numHosts][];<a name="line.198"></a>
+<span class="sourceLineNo">199</span>    serversPerRack = new int[numRacks][];<a name="line.199"></a>
+<span class="sourceLineNo">200</span>    regions = new RegionInfo[numRegions];<a name="line.200"></a>
+<span class="sourceLineNo">201</span>    regionIndexToServerIndex = new int[numRegions];<a name="line.201"></a>
+<span class="sourceLineNo">202</span>    initialRegionIndexToServerIndex = new int[numRegions];<a name="line.202"></a>
+<span class="sourceLineNo">203</span>    regionIndexToTableIndex = new int[numRegions];<a name="line.203"></a>
+<span class="sourceLineNo">204</span>    regionIndexToPrimaryIndex = new int[numRegions];<a name="line.204"></a>
+<span class="sourceLineNo">205</span>    regionLoads = new Deque[numRegions];<a name="line.205"></a>
+<span class="sourceLineNo">206</span><a name="line.206"></a>
+<span class="sourceLineNo">207</span>    regionLocations = new int[numRegions][];<a name="line.207"></a>
+<span class="sourceLineNo">208</span>    serverIndicesSortedByRegionCount = new Integer[numServers];<a name="line.208"></a>
+<span class="sourceLineNo">209</span>    serverIndicesSortedByLocality = new Integer[numServers];<a name="line.209"></a>
+<span class="sourceLineNo">210</span>    localityPerServer = new float[numServers];<a name="line.210"></a>
+<span class="sourceLineNo">211</span><a name="line.211"></a>
+<span class="sourceLineNo">212</span>    serverIndexToHostIndex = new int[numServers];<a name="line.212"></a>
+<span class="sourceLineNo">213</span>    serverIndexToRackIndex = new int[numServers];<a name="line.213"></a>
+<span class="sourceLineNo">214</span>    regionsPerServer = new int[numServers][];<a name="line.214"></a>
+<span class="sourceLineNo">215</span>    serverIndexToRegionsOffset = new int[numServers];<a name="line.215"></a>
+<span class="sourceLineNo">216</span>    regionsPerHost = new int[numHosts][];<a name="line.216"></a>
+<span class="sourceLineNo">217</span>    regionsPerRack = new int[numRacks][];<a name="line.217"></a>
+<span class="sourceLineNo">218</span>    colocatedReplicaCountsPerServer = new Int2IntCounterMap[numServers];<a name="line.218"></a>
+<span class="sourceLineNo">219</span>    colocatedReplicaCountsPerHost = new Int2IntCounterMap[numHosts];<a name="line.219"></a>
+<span class="sourceLineNo">220</span>    colocatedReplicaCountsPerRack = new Int2IntCounterMap[numRacks];<a name="line.220"></a>
+<span class="sourceLineNo">221</span><a name="line.221"></a>
+<span class="sourceLineNo">222</span>    int tableIndex = 0, regionIndex = 0, regionPerServerIndex = 0;<a name="line.222"></a>
+<span class="sourceLineNo">223</span><a name="line.223"></a>
+<span class="sourceLineNo">224</span>    for (Map.Entry&lt;ServerName, List&lt;RegionInfo&gt;&gt; entry : clusterState.entrySet()) {<a name="line.224"></a>
+<span class="sourceLineNo">225</span>      if (entry.getKey() == null) {<a name="line.225"></a>
+<span class="sourceLineNo">226</span>        LOG.warn("SERVERNAME IS NULL, skipping " + entry.getValue());<a name="line.226"></a>
+<span class="sourceLineNo">227</span>        continue;<a name="line.227"></a>
+<span class="sourceLineNo">228</span>      }<a name="line.228"></a>
+<span class="sourceLineNo">229</span>      int serverIndex = serversToIndex.get(entry.getKey().getAddress());<a name="line.229"></a>
+<span class="sourceLineNo">230</span><a name="line.230"></a>
+<span class="sourceLineNo">231</span>      // keep the servername if this is the first server name for this hostname<a name="line.231"></a>
+<span class="sourceLineNo">232</span>      // or this servername has the newest startcode.<a name="line.232"></a>
+<span class="sourceLineNo">233</span>      if (servers[serverIndex] == null ||<a name="line.233"></a>
+<span class="sourceLineNo">234</span>        servers[serverIndex].getStartcode() &lt; entry.getKey().getStartcode()) {<a name="line.234"></a>
+<span class="sourceLineNo">235</span>        servers[serverIndex] = entry.getKey();<a name="line.235"></a>
+<span class="sourceLineNo">236</span>      }<a name="line.236"></a>
+<span class="sourceLineNo">237</span><a name="line.237"></a>
+<span class="sourceLineNo">238</span>      if (regionsPerServer[serverIndex] != null) {<a name="line.238"></a>
+<span class="sourceLineNo">239</span>        // there is another server with the same hostAndPort in ClusterState.<a name="line.239"></a>
+<span class="sourceLineNo">240</span>        // allocate the array for the total size<a name="line.240"></a>
+<span class="sourceLineNo">241</span>        regionsPerServer[serverIndex] =<a name="line.241"></a>
+<span class="sourceLineNo">242</span>          new int[entry.getValue().size() + regionsPerServer[serverIndex].length];<a name="line.242"></a>
+<span class="sourceLineNo">243</span>      } else {<a name="line.243"></a>
+<span class="sourceLineNo">244</span>        regionsPerServer[serverIndex] = new int[entry.getValue().size()];<a name="line.244"></a>
+<span class="sourceLineNo">245</span>      }<a name="line.245"></a>
+<span class="sourceLineNo">246</span>      colocatedReplicaCountsPerServer[serverIndex] = new Int2IntCounterMap(<a name="line.246"></a>
+<span class="sourceLineNo">247</span>        regionsPerServer[serverIndex].length, Hashing.DEFAULT_LOAD_FACTOR, 0);<a name="line.247"></a>
+<span class="sourceLineNo">248</span>      serverIndicesSortedByRegionCount[serverIndex] = serverIndex;<a name="line.248"></a>
+<span class="sourceLineNo">249</span>      serverIndicesSortedByLocality[serverIndex] = serverIndex;<a name="line.249"></a>
 <span class="sourceLineNo">250</span>    }<a name="line.250"></a>
-<span class="sourceLineNo">251</span>    racks = new String[numRacks];<a name="line.251"></a>
-<span class="sourceLineNo">252</span>    for (Map.Entry&lt;String, Integer&gt; entry : racksToIndex.entrySet()) {<a name="line.252"></a>
-<span class="sourceLineNo">253</span>      racks[entry.getValue()] = entry.getKey();<a name="line.253"></a>
-<span class="sourceLineNo">254</span>    }<a name="line.254"></a>
-<span class="sourceLineNo">255</span><a name="line.255"></a>
-<span class="sourceLineNo">256</span>    for (Map.Entry&lt;ServerName, List&lt;RegionInfo&gt;&gt; entry : clusterState.entrySet()) {<a name="line.256"></a>
-<span class="sourceLineNo">257</span>      int serverIndex = serversToIndex.get(entry.getKey().getAddress());<a name="line.257"></a>
-<span class="sourceLineNo">258</span>      regionPerServerIndex = serverIndexToRegionsOffset[serverIndex];<a name="line.258"></a>
-<span class="sourceLineNo">259</span><a name="line.259"></a>
-<span class="sourceLineNo">260</span>      int hostIndex = hostsToIndex.get(entry.getKey().getHostname());<a name="line.260"></a>
-<span class="sourceLineNo">261</span>      serverIndexToHostIndex[serverIndex] = hostIndex;<a name="line.261"></a>
-<span class="sourceLineNo">262</span><a name="line.262"></a>
-<span class="sourceLineNo">263</span>      int rackIndex = racksToIndex.get(this.rackManager.getRack(entry.getKey()));<a name="line.263"></a>
-<span class="sourceLineNo">264</span>      serverIndexToRackIndex[serverIndex] = rackIndex;<a name="line.264"></a>
-<span class="sourceLineNo">265</span><a name="line.265"></a>
-<span class="sourceLineNo">266</span>      for (RegionInfo region : entry.getValue()) {<a name="line.266"></a>
-<span class="sourceLineNo">267</span>        registerRegion(region, regionIndex, serverIndex, loads, regionFinder);<a name="line.267"></a>
-<span class="sourceLineNo">268</span>        regionsPerServer[serverIndex][regionPerServerIndex++] = regionIndex;<a name="line.268"></a>
-<span class="sourceLineNo">269</span>        regionIndex++;<a name="line.269"></a>
-<span class="sourceLineNo">270</span>      }<a name="line.270"></a>
-<span class="sourceLineNo">271</span>      serverIndexToRegionsOffset[serverIndex] = regionPerServerIndex;<a name="line.271"></a>
-<span class="sourceLineNo">272</span>    }<a name="line.272"></a>
-<span class="sourceLineNo">273</span><a name="line.273"></a>
-<span class="sourceLineNo">274</span>    for (RegionInfo region : unassignedRegions) {<a name="line.274"></a>
-<span class="sourceLineNo">275</span>      registerRegion(region, regionIndex, -1, loads, regionFinder);<a name="line.275"></a>
-<span class="sourceLineNo">276</span>      regionIndex++;<a name="line.276"></a>
+<span class="sourceLineNo">251</span><a name="line.251"></a>
+<span class="sourceLineNo">252</span>    hosts = new String[numHosts];<a name="line.252"></a>
+<span class="sourceLineNo">253</span>    for (Map.Entry&lt;String, Integer&gt; entry : hostsToIndex.entrySet()) {<a name="line.253"></a>
+<span class="sourceLineNo">254</span>      hosts[entry.getValue()] = entry.getKey();<a name="line.254"></a>
+<span class="sourceLineNo">255</span>    }<a name="line.255"></a>
+<span class="sourceLineNo">256</span>    racks = new String[numRacks];<a name="line.256"></a>
+<span class="sourceLineNo">257</span>    for (Map.Entry&lt;String, Integer&gt; entry : racksToIndex.entrySet()) {<a name="line.257"></a>
+<span class="sourceLineNo">258</span>      racks[entry.getValue()] = entry.getKey();<a name="line.258"></a>
+<span class="sourceLineNo">259</span>    }<a name="line.259"></a>
+<span class="sourceLineNo">260</span><a name="line.260"></a>
+<span class="sourceLineNo">261</span>    for (Map.Entry&lt;ServerName, List&lt;RegionInfo&gt;&gt; entry : clusterState.entrySet()) {<a name="line.261"></a>
+<span class="sourceLineNo">262</span>      int serverIndex = serversToIndex.get(entry.getKey().getAddress());<a name="line.262"></a>
+<span class="sourceLineNo">263</span>      regionPerServerIndex = serverIndexToRegionsOffset[serverIndex];<a name="line.263"></a>
+<span class="sourceLineNo">264</span><a name="line.264"></a>
+<span class="sourceLineNo">265</span>      int hostIndex = hostsToIndex.get(entry.getKey().getHostname());<a name="line.265"></a>
+<span class="sourceLineNo">266</span>      serverIndexToHostIndex[serverIndex] = hostIndex;<a name="line.266"></a>
+<span class="sourceLineNo">267</span><a name="line.267"></a>
+<span class="sourceLineNo">268</span>      int rackIndex = racksToIndex.get(this.rackManager.getRack(entry.getKey()));<a name="line.268"></a>
+<span class="sourceLineNo">269</span>      serverIndexToRackIndex[serverIndex] = rackIndex;<a name="line.269"></a>
+<span class="sourceLineNo">270</span><a name="line.270"></a>
+<span class="sourceLineNo">271</span>      for (RegionInfo region : entry.getValue()) {<a name="line.271"></a>
+<span class="sourceLineNo">272</span>        registerRegion(region, regionIndex, serverIndex, loads, regionFinder);<a name="line.272"></a>
+<span class="sourceLineNo">273</span>        regionsPerServer[serverIndex][regionPerServerIndex++] = regionIndex;<a name="line.273"></a>
+<span class="sourceLineNo">274</span>        regionIndex++;<a name="line.274"></a>
+<span class="sourceLineNo">275</span>      }<a name="line.275"></a>
+<span class="sourceLineNo">276</span>      serverIndexToRegionsOffset[serverIndex] = regionPerServerIndex;<a name="line.276"></a>
 <span class="sourceLineNo">277</span>    }<a name="line.277"></a>
 <span class="sourceLineNo">278</span><a name="line.278"></a>
-<span class="sourceLineNo">279</span>    for (int i = 0; i &lt; serversPerHostList.size(); i++) {<a name="line.279"></a>
-<span class="sourceLineNo">280</span>      serversPerHost[i] = new int[serversPerHostList.get(i).size()];<a name="line.280"></a>
-<span class="sourceLineNo">281</span>      for (int j = 0; j &lt; serversPerHost[i].length; j++) {<a name="line.281"></a>
-<span class="sourceLineNo">282</span>        serversPerHost[i][j] = serversPerHostList.get(i).get(j);<a name="line.282"></a>
-<span class="sourceLineNo">283</span>      }<a name="line.283"></a>
-<span class="sourceLineNo">284</span>      if (serversPerHost[i].length &gt; 1) {<a name="line.284"></a>
-<span class="sourceLineNo">285</span>        multiServersPerHost = true;<a name="line.285"></a>
-<span class="sourceLineNo">286</span>      }<a name="line.286"></a>
-<span class="sourceLineNo">287</span>    }<a name="line.287"></a>
-<span class="sourceLineNo">288</span><a name="line.288"></a>
-<span class="sourceLineNo">289</span>    for (int i = 0; i &lt; serversPerRackList.size(); i++) {<a name="line.289"></a>
-<span class="sourceLineNo">290</span>      serversPerRack[i] = new int[serversPerRackList.get(i).size()];<a name="line.290"></a>
-<span class="sourceLineNo">291</span>      for (int j = 0; j &lt; serversPerRack[i].length; j++) {<a name="line.291"></a>
-<span class="sourceLineNo">292</span>        serversPerRack[i][j] = serversPerRackList.get(i).get(j);<a name="line.292"></a>
-<span class="sourceLineNo">293</span>      }<a name="line.293"></a>
-<span class="sourceLineNo">294</span>    }<a name="line.294"></a>
-<span class="sourceLineNo">295</span><a name="line.295"></a>
-<span class="sourceLineNo">296</span>    numTables = tables.size();<a name="line.296"></a>
-<span class="sourceLineNo">297</span>    LOG.debug("Number of tables={}", numTables);<a name="line.297"></a>
-<span class="sourceLineNo">298</span>    numRegionsPerServerPerTable = new int[numServers][numTables];<a name="line.298"></a>
-<span class="sourceLineNo">299</span>    numRegionsPerTable = new int[numTables];<a name="line.299"></a>
+<span class="sourceLineNo">279</span>    for (RegionInfo region : unassignedRegions) {<a name="line.279"></a>
+<span class="sourceLineNo">280</span>      registerRegion(region, regionIndex, -1, loads, regionFinder);<a name="line.280"></a>
+<span class="sourceLineNo">281</span>      regionIndex++;<a name="line.281"></a>
+<span class="sourceLineNo">282</span>    }<a name="line.282"></a>
+<span class="sourceLineNo">283</span><a name="line.283"></a>
+<span class="sourceLineNo">284</span>    for (int i = 0; i &lt; serversPerHostList.size(); i++) {<a name="line.284"></a>
+<span class="sourceLineNo">285</span>      serversPerHost[i] = new int[serversPerHostList.get(i).size()];<a name="line.285"></a>
+<span class="sourceLineNo">286</span>      for (int j = 0; j &lt; serversPerHost[i].length; j++) {<a name="line.286"></a>
+<span class="sourceLineNo">287</span>        serversPerHost[i][j] = serversPerHostList.get(i).get(j);<a name="line.287"></a>
+<span class="sourceLineNo">288</span>      }<a name="line.288"></a>
+<span class="sourceLineNo">289</span>      if (serversPerHost[i].length &gt; 1) {<a name="line.289"></a>
+<span class="sourceLineNo">290</span>        multiServersPerHost = true;<a name="line.290"></a>
+<span class="sourceLineNo">291</span>      }<a name="line.291"></a>
+<span class="sourceLineNo">292</span>    }<a name="line.292"></a>
+<span class="sourceLineNo">293</span><a name="line.293"></a>
+<span class="sourceLineNo">294</span>    for (int i = 0; i &lt; serversPerRackList.size(); i++) {<a name="line.294"></a>
+<span class="sourceLineNo">295</span>      serversPerRack[i] = new int[serversPerRackList.get(i).size()];<a name="line.295"></a>
+<span class="sourceLineNo">296</span>      for (int j = 0; j &lt; serversPerRack[i].length; j++) {<a name="line.296"></a>
+<span class="sourceLineNo">297</span>        serversPerRack[i][j] = serversPerRackList.get(i).get(j);<a name="line.297"></a>
+<span class="sourceLineNo">298</span>      }<a name="line.298"></a>
+<span class="sourceLineNo">299</span>    }<a name="line.299"></a>
 <span class="sourceLineNo">300</span><a name="line.300"></a>
-<span class="sourceLineNo">301</span>    for (int i = 0; i &lt; numServers; i++) {<a name="line.301"></a>
-<span class="sourceLineNo">302</span>      for (int j = 0; j &lt; numTables; j++) {<a name="line.302"></a>
-<span class="sourceLineNo">303</span>        numRegionsPerServerPerTable[i][j] = 0;<a name="line.303"></a>
-<span class="sourceLineNo">304</span>      }<a name="line.304"></a>
-<span class="sourceLineNo">305</span>    }<a name="line.305"></a>
-<span class="sourceLineNo">306</span><a name="line.306"></a>
-<span class="sourceLineNo">307</span>    for (int i = 0; i &lt; regionIndexToServerIndex.length; i++) {<a name="line.307"></a>
-<span class="sourceLineNo">308</span>      if (regionIndexToServerIndex[i] &gt;= 0) {<a name="line.308"></a>
-<span class="sourceLineNo">309</span>        numRegionsPerServerPerTable[regionIndexToServerIndex[i]][regionIndexToTableIndex[i]]++;<a name="line.309"></a>
-<span class="sourceLineNo">310</span>        numRegionsPerTable[regionIndexToTableIndex[i]]++;<a name="line.310"></a>
-<span class="sourceLineNo">311</span>      }<a name="line.311"></a>
-<span class="sourceLineNo">312</span>    }<a name="line.312"></a>
-<span class="sourceLineNo">313</span><a name="line.313"></a>
-<span class="sourceLineNo">314</span>    // Avoid repeated computation for planning<a name="line.314"></a>
-<span class="sourceLineNo">315</span>    meanRegionsPerTable = new double[numTables];<a name="line.315"></a>
-<span class="sourceLineNo">316</span>    regionSkewByTable = new double[numTables];<a name="line.316"></a>
-<span class="sourceLineNo">317</span>    maxRegionSkewByTable  = new double[numTables];<a name="line.317"></a>
-<span class="sourceLineNo">318</span>    minRegionSkewByTable = new double[numTables];<a name="line.318"></a>
-<span class="sourceLineNo">319</span><a name="line.319"></a>
-<span class="sourceLineNo">320</span>    for (int i = 0; i &lt; numTables; i++) {<a name="line.320"></a>
-<span class="sourceLineNo">321</span>      meanRegionsPerTable[i] = Double.valueOf(numRegionsPerTable[i]) / numServers;<a name="line.321"></a>
-<span class="sourceLineNo">322</span>      minRegionSkewByTable[i] += DoubleArrayCost.getMinSkew(numRegionsPerTable[i], numServers);<a name="line.322"></a>
-<span class="sourceLineNo">323</span>      maxRegionSkewByTable[i] += DoubleArrayCost.getMaxSkew(numRegionsPerTable[i], numServers);<a name="line.323"></a>
-<span class="sourceLineNo">324</span>    }<a name="line.324"></a>
-<span class="sourceLineNo">325</span><a name="line.325"></a>
-<span class="sourceLineNo">326</span>    for (int[] aNumRegionsPerServerPerTable : numRegionsPerServerPerTable) {<a name="line.326"></a>
-<span class="sourceLineNo">327</span>      for (int tableIdx = 0; tableIdx &lt; aNumRegionsPerServerPerTable.length; tableIdx++) {<a name="line.327"></a>
-<span class="sourceLineNo">328</span>        regionSkewByTable[tableIdx] += Math.abs(aNumRegionsPerServerPerTable[tableIdx] -<a name="line.328"></a>
-<span class="sourceLineNo">329</span>          meanRegionsPerTable[tableIdx]);<a name="line.329"></a>
-<span class="sourceLineNo">330</span>      }<a name="line.330"></a>
-<span class="sourceLineNo">331</span>    }<a name="line.331"></a>
-<span class="sourceLineNo">332</span><a name="line.332"></a>
-<span class="sourceLineNo">333</span>    for (int i = 0; i &lt; regions.length; i++) {<a name="line.333"></a>
-<span class="sourceLineNo">334</span>      RegionInfo info = regions[i];<a name="line.334"></a>
-<span class="sourceLineNo">335</span>      if (RegionReplicaUtil.isDefaultReplica(info)) {<a name="line.335"></a>
-<span class="sourceLineNo">336</span>        regionIndexToPrimaryIndex[i] = i;<a name="line.336"></a>
-<span class="sourceLineNo">337</span>      } else {<a name="line.337"></a>
-<span class="sourceLineNo">338</span>        hasRegionReplicas = true;<a name="line.338"></a>
-<span class="sourceLineNo">339</span>        RegionInfo primaryInfo = RegionReplicaUtil.getRegionInfoForDefaultReplica(info);<a name="line.339"></a>
-<span class="sourceLineNo">340</span>        regionIndexToPrimaryIndex[i] = regionsToIndex.getOrDefault(primaryInfo, -1);<a name="line.340"></a>
-<span class="sourceLineNo">341</span>      }<a name="line.341"></a>
-<span class="sourceLineNo">342</span>    }<a name="line.342"></a>
-<span class="sourceLineNo">343</span><a name="line.343"></a>
-<span class="sourceLineNo">344</span>    for (int i = 0; i &lt; regionsPerServer.length; i++) {<a name="line.344"></a>
-<span class="sourceLineNo">345</span>      primariesOfRegionsPerServer[i] = new int[regionsPerServer[i].length];<a name="line.345"></a>
-<span class="sourceLineNo">346</span>      for (int j = 0; j &lt; regionsPerServer[i].length; j++) {<a name="line.346"></a>
-<span class="sourceLineNo">347</span>        int primaryIndex = regionIndexToPrimaryIndex[regionsPerServer[i][j]];<a name="line.347"></a>
-<span class="sourceLineNo">348</span>        primariesOfRegionsPerServer[i][j] = primaryIndex;<a name="line.348"></a>
-<span class="sourceLineNo">349</span>      }<a name="line.349"></a>
-<span class="sourceLineNo">350</span>      // sort the regions by primaries.<a name="line.350"></a>
-<span class="sourceLineNo">351</span>      Arrays.sort(primariesOfRegionsPerServer[i]);<a name="line.351"></a>
-<span class="sourceLineNo">352</span>    }<a name="line.352"></a>
-<span class="sourceLineNo">353</span><a name="line.353"></a>
-<span class="sourceLineNo">354</span>    // compute regionsPerHost<a name="line.354"></a>
-<span class="sourceLineNo">355</span>    if (multiServersPerHost) {<a name="line.355"></a>
-<span class="sourceLineNo">356</span>      for (int i = 0; i &lt; serversPerHost.length; i++) {<a name="line.356"></a>
-<span class="sourceLineNo">357</span>        int numRegionsPerHost = 0;<a name="line.357"></a>
-<span class="sourceLineNo">358</span>        for (int j = 0; j &lt; serversPerHost[i].length; j++) {<a name="line.358"></a>
-<span class="sourceLineNo">359</span>          numRegionsPerHost += regionsPerServer[serversPerHost[i][j]].length;<a name="line.359"></a>
-<span class="sourceLineNo">360</span>        }<a name="line.360"></a>
-<span class="sourceLineNo">361</span>        regionsPerHost[i] = new int[numRegionsPerHost];<a name="line.361"></a>
-<span class="sourceLineNo">362</span>        primariesOfRegionsPerHost[i] = new int[numRegionsPerHost];<a name="line.362"></a>
-<span class="sourceLineNo">363</span>      }<a name="line.363"></a>
-<span class="sourceLineNo">364</span>      for (int i = 0; i &lt; serversPerHost.length; i++) {<a name="line.364"></a>
-<span class="sourceLineNo">365</span>        int numRegionPerHostIndex = 0;<a name="line.365"></a>
-<span class="sourceLineNo">366</span>        for (int j = 0; j &lt; serversPerHost[i].length; j++) {<a name="line.366"></a>
-<span class="sourceLineNo">367</span>          for (int k = 0; k &lt; regionsPerServer[serversPerHost[i][j]].length; k++) {<a name="line.367"></a>
-<span class="sourceLineNo">368</span>            int region = regionsPerServer[serversPerHost[i][j]][k];<a name="line.368"></a>
-<span class="sourceLineNo">369</span>            regionsPerHost[i][numRegionPerHostIndex] = region;<a name="line.369"></a>
-<span class="sourceLineNo">370</span>            int primaryIndex = regionIndexToPrimaryIndex[region];<a name="line.370"></a>
-<span class="sourceLineNo">371</span>            primariesOfRegionsPerHost[i][numRegionPerHostIndex] = primaryIndex;<a name="line.371"></a>
-<span class="sourceLineNo">372</span>            numRegionPerHostIndex++;<a name="line.372"></a>
-<span class="sourceLineNo">373</span>          }<a name="line.373"></a>
-<span class="sourceLineNo">374</span>        }<a name="line.374"></a>
-<span class="sourceLineNo">375</span>        // sort the regions by primaries.<a name="line.375"></a>
-<span class="sourceLineNo">376</span>        Arrays.sort(primariesOfRegionsPerHost[i]);<a name="line.376"></a>
+<span class="sourceLineNo">301</span>    numTables = tables.size();<a name="line.301"></a>
+<span class="sourceLineNo">302</span>    LOG.debug("Number of tables={}", numTables);<a name="line.302"></a>
+<span class="sourceLineNo">303</span>    numRegionsPerServerPerTable = new int[numServers][numTables];<a name="line.303"></a>
+<span class="sourceLineNo">304</span>    numRegionsPerTable = new int[numTables];<a name="line.304"></a>
+<span class="sourceLineNo">305</span><a name="line.305"></a>
+<span class="sourceLineNo">306</span>    for (int i = 0; i &lt; numServers; i++) {<a name="line.306"></a>
+<span class="sourceLineNo">307</span>      for (int j = 0; j &lt; numTables; j++) {<a name="line.307"></a>
+<span class="sourceLineNo">308</span>        numRegionsPerServerPerTable[i][j] = 0;<a name="line.308"></a>
+<span class="sourceLineNo">309</span>      }<a name="line.309"></a>
+<span class="sourceLineNo">310</span>    }<a name="line.310"></a>
+<span class="sourceLineNo">311</span><a name="line.311"></a>
+<span class="sourceLineNo">312</span>    for (int i = 0; i &lt; regionIndexToServerIndex.length; i++) {<a name="line.312"></a>
+<span class="sourceLineNo">313</span>      if (regionIndexToServerIndex[i] &gt;= 0) {<a name="line.313"></a>
+<span class="sourceLineNo">314</span>        numRegionsPerServerPerTable[regionIndexToServerIndex[i]][regionIndexToTableIndex[i]]++;<a name="line.314"></a>
+<span class="sourceLineNo">315</span>        numRegionsPerTable[regionIndexToTableIndex[i]]++;<a name="line.315"></a>
+<span class="sourceLineNo">316</span>      }<a name="line.316"></a>
+<span class="sourceLineNo">317</span>    }<a name="line.317"></a>
+<span class="sourceLineNo">318</span><a name="line.318"></a>
+<span class="sourceLineNo">319</span>    // Avoid repeated computation for planning<a name="line.319"></a>
+<span class="sourceLineNo">320</span>    meanRegionsPerTable = new double[numTables];<a name="line.320"></a>
+<span class="sourceLineNo">321</span>    regionSkewByTable = new double[numTables];<a name="line.321"></a>
+<span class="sourceLineNo">322</span>    maxRegionSkewByTable  = new double[numTables];<a name="line.322"></a>
+<span class="sourceLineNo">323</span>    minRegionSkewByTable = new double[numTables];<a name="line.323"></a>
+<span class="sourceLineNo">324</span><a name="line.324"></a>
+<span class="sourceLineNo">325</span>    for (int i = 0; i &lt; numTables; i++) {<a name="line.325"></a>
+<span class="sourceLineNo">326</span>      meanRegionsPerTable[i] = Double.valueOf(numRegionsPerTable[i]) / numServers;<a name="line.326"></a>
+<span class="sourceLineNo">327</span>      minRegionSkewByTable[i] += DoubleArrayCost.getMinSkew(numRegionsPerTable[i], numServers);<a name="line.327"></a>
+<span class="sourceLineNo">328</span>      maxRegionSkewByTable[i] += DoubleArrayCost.getMaxSkew(numRegionsPerTable[i], numServers);<a name="line.328"></a>
+<span class="sourceLineNo">329</span>    }<a name="line.329"></a>
+<span class="sourceLineNo">330</span><a name="line.330"></a>
+<span class="sourceLineNo">331</span>    for (int[] aNumRegionsPerServerPerTable : numRegionsPerServerPerTable) {<a name="line.331"></a>
+<span class="sourceLineNo">332</span>      for (int tableIdx = 0; tableIdx &lt; aNumRegionsPerServerPerTable.length; tableIdx++) {<a name="line.332"></a>
+<span class="sourceLineNo">333</span>        regionSkewByTable[tableIdx] += Math.abs(aNumRegionsPerServerPerTable[tableIdx] -<a name="line.333"></a>
+<span class="sourceLineNo">334</span>          meanRegionsPerTable[tableIdx]);<a name="line.334"></a>
+<span class="sourceLineNo">335</span>      }<a name="line.335"></a>
+<span class="sourceLineNo">336</span>    }<a name="line.336"></a>
+<span class="sourceLineNo">337</span><a name="line.337"></a>
+<span class="sourceLineNo">338</span>    for (int i = 0; i &lt; regions.length; i++) {<a name="line.338"></a>
+<span class="sourceLineNo">339</span>      RegionInfo info = regions[i];<a name="line.339"></a>
+<span class="sourceLineNo">340</span>      if (RegionReplicaUtil.isDefaultReplica(info)) {<a name="line.340"></a>
+<span class="sourceLineNo">341</span>        regionIndexToPrimaryIndex[i] = i;<a name="line.341"></a>
+<span class="sourceLineNo">342</span>      } else {<a name="line.342"></a>
+<span class="sourceLineNo">343</span>        hasRegionReplicas = true;<a name="line.343"></a>
+<span class="sourceLineNo">344</span>        RegionInfo primaryInfo = RegionReplicaUtil.getRegionInfoForDefaultReplica(info);<a name="line.344"></a>
+<span class="sourceLineNo">345</span>        regionIndexToPrimaryIndex[i] = regionsToIndex.getOrDefault(primaryInfo, -1);<a name="line.345"></a>
+<span class="sourceLineNo">346</span>      }<a name="line.346"></a>
+<span class="sourceLineNo">347</span>    }<a name="line.347"></a>
+<span class="sourceLineNo">348</span><a name="line.348"></a>
+<span class="sourceLineNo">349</span>    for (int i = 0; i &lt; regionsPerServer.length; i++) {<a name="line.349"></a>
+<span class="sourceLineNo">350</span>      colocatedReplicaCountsPerServer[i] = new Int2IntCounterMap(<a name="line.350"></a>
+<span class="sourceLineNo">351</span>        regionsPerServer[i].length, Hashing.DEFAULT_LOAD_FACTOR, 0);<a name="line.351"></a>
+<span class="sourceLineNo">352</span>      for (int j = 0; j &lt; regionsPerServer[i].length; j++) {<a name="line.352"></a>
+<span class="sourceLineNo">353</span>        int primaryIndex = regionIndexToPrimaryIndex[regionsPerServer[i][j]];<a name="line.353"></a>
+<span class="sourceLineNo">354</span>        colocatedReplicaCountsPerServer[i].getAndIncrement(primaryIndex);<a name="line.354"></a>
+<span class="sourceLineNo">355</span>      }<a name="line.355"></a>
+<span class="sourceLineNo">356</span>    }<a name="line.356"></a>
+<span class="sourceLineNo">357</span>    // compute regionsPerHost<a name="line.357"></a>
+<span class="sourceLineNo">358</span>    if (multiServersPerHost) {<a name="line.358"></a>
+<span class="sourceLineNo">359</span>      populateRegionPerLocationFromServer(regionsPerHost, colocatedReplicaCountsPerHost,<a name="line.359"></a>
+<span class="sourceLineNo">360</span>        serversPerHost);<a name="line.360"></a>
+<span class="sourceLineNo">361</span>    }<a name="line.361"></a>
+<span class="sourceLineNo">362</span><a name="line.362"></a>
+<span class="sourceLineNo">363</span>    // compute regionsPerRack<a name="line.363"></a>
+<span class="sourceLineNo">364</span>    if (numRacks &gt; 1) {<a name="line.364"></a>
+<span class="sourceLineNo">365</span>      populateRegionPerLocationFromServer(regionsPerRack, colocatedReplicaCountsPerRack,<a name="line.365"></a>
+<span class="sourceLineNo">366</span>        serversPerRack);<a name="line.366"></a>
+<span class="sourceLineNo">367</span>    }<a name="line.367"></a>
+<span class="sourceLineNo">368</span>  }<a name="line.368"></a>
+<span class="sourceLineNo">369</span><a name="line.369"></a>
+<span class="sourceLineNo">370</span>  private void populateRegionPerLocationFromServer(int[][] regionsPerLocation,<a name="line.370"></a>
+<span class="sourceLineNo">371</span>    Int2IntCounterMap[] colocatedReplicaCountsPerLocation,<a name="line.371"></a>
+<span class="sourceLineNo">372</span>    int[][] serversPerLocation) {<a name="line.372"></a>
+<span class="sourceLineNo">373</span>    for (int i = 0; i &lt; serversPerLocation.length; i++) {<a name="line.373"></a>
+<span class="sourceLineNo">374</span>      int numRegionsPerLocation = 0;<a name="line.374"></a>
+<span class="sourceLineNo">375</span>      for (int j = 0; j &lt; serversPerLocation[i].length; j++) {<a name="line.375"></a>
+<span class="sourceLineNo">376</span>        numRegionsPerLocation += regionsPerServer[serversPerLocation[i][j]].length;<a name="line.376"></a>
 <span class="sourceLineNo">377</span>      }<a name="line.377"></a>
-<span class="sourceLineNo">378</span>    }<a name="line.378"></a>
-<span class="sourceLineNo">379</span><a name="line.379"></a>
-<span class="sourceLineNo">380</span>    // compute regionsPerRack<a name="line.380"></a>
-<span class="sourceLineNo">381</span>    if (numRacks &gt; 1) {<a name="line.381"></a>
-<span class="sourceLineNo">382</span>      for (int i = 0; i &lt; serversPerRack.length; i++) {<a name="line.382"></a>
-<span class="sourceLineNo">383</span>        int numRegionsPerRack = 0;<a name="line.383"></a>
-<span class="sourceLineNo">384</span>        for (int j = 0; j &lt; serversPerRack[i].length; j++) {<a name="line.384"></a>
-<span class="sourceLineNo">385</span>          numRegionsPerRack += regionsPerServer[serversPerRack[i][j]].length;<a name="line.385"></a>
-<span class="sourceLineNo">386</span>        }<a name="line.386"></a>
-<span class="sourceLineNo">387</span>        regionsPerRack[i] = new int[numRegionsPerRack];<a name="line.387"></a>
-<span class="sourceLineNo">388</span>        primariesOfRegionsPerRack[i] = new int[numRegionsPerRack];<a name="line.388"></a>
-<span class="sourceLineNo">389</span>      }<a name="line.389"></a>
-<span class="sourceLineNo">390</span><a name="line.390"></a>
-<span class="sourceLineNo">391</span>      for (int i = 0; i &lt; serversPerRack.length; i++) {<a name="line.391"></a>
-<span class="sourceLineNo">392</span>        int numRegionPerRackIndex = 0;<a name="line.392"></a>
-<span class="sourceLineNo">393</span>        for (int j = 0; j &lt; serversPerRack[i].length; j++) {<a name="line.393"></a>
-<span class="sourceLineNo">394</span>          for (int k = 0; k &lt; regionsPerServer[serversPerRack[i][j]].length; k++) {<a name="line.394"></a>
-<span class="sourceLineNo">395</span>            int region = regionsPerServer[serversPerRack[i][j]][k];<a name="line.395"></a>
-<span class="sourceLineNo">396</span>            regionsPerRack[i][numRegionPerRackIndex] = region;<a name="line.396"></a>
-<span class="sourceLineNo">397</span>            int primaryIndex = regionIndexToPrimaryIndex[region];<a name="line.397"></a>
-<span class="sourceLineNo">398</span>            primariesOfRegionsPerRack[i][numRegionPerRackIndex] = primaryIndex;<a name="line.398"></a>
-<span class="sourceLineNo">399</span>            numRegionPerRackIndex++;<a name="line.399"></a>
-<span class="sourceLineNo">400</span>          }<a name="line.400"></a>
-<span class="sourceLineNo">401</span>        }<a name="line.401"></a>
-<span class="sourceLineNo">402</span>        // sort the regions by primaries.<a name="line.402"></a>
-<span class="sourceLineNo">403</span>        Arrays.sort(primariesOfRegionsPerRack[i]);<a name="line.403"></a>
-<span class="sourceLineNo">404</span>      }<a name="line.404"></a>
+<span class="sourceLineNo">378</span>      regionsPerLocation[i] = new int[numRegionsPerLocation];<a name="line.378"></a>
+<span class="sourceLineNo">379</span>      colocatedReplicaCountsPerLocation[i] = new Int2IntCounterMap(numRegionsPerLocation,<a name="line.379"></a>
+<span class="sourceLineNo">380</span>        Hashing.DEFAULT_LOAD_FACTOR, 0);<a name="line.380"></a>
+<span class="sourceLineNo">381</span>    }<a name="line.381"></a>
+<span class="sourceLineNo">382</span><a name="line.382"></a>
+<span class="sourceLineNo">383</span>    for (int i = 0; i &lt; serversPerLocation.length; i++) {<a name="line.383"></a>
+<span class="sourceLineNo">384</span>      int numRegionPerLocationIndex = 0;<a name="line.384"></a>
+<span class="sourceLineNo">385</span>      for (int j = 0; j &lt; serversPerLocation[i].length; j++) {<a name="line.385"></a>
+<span class="sourceLineNo">386</span>        for (int k = 0; k &lt; regionsPerServer[serversPerLocation[i][j]].length; k++) {<a name="line.386"></a>
+<span class="sourceLineNo">387</span>          int region = regionsPerServer[serversPerLocation[i][j]][k];<a name="line.387"></a>
+<span class="sourceLineNo">388</span>          regionsPerLocation[i][numRegionPerLocationIndex] = region;<a name="line.388"></a>
+<span class="sourceLineNo">389</span>          int primaryIndex = regionIndexToPrimaryIndex[region];<a name="line.389"></a>
+<span class="sourceLineNo">390</span>          colocatedReplicaCountsPerLocation[i].getAndIncrement(primaryIndex);<a name="line.390"></a>
+<span class="sourceLineNo">391</span>          numRegionPerLocationIndex++;<a name="line.391"></a>
+<span class="sourceLineNo">392</span>        }<a name="line.392"></a>
+<span class="sourceLineNo">393</span>      }<a name="line.393"></a>
+<span class="sourceLineNo">394</span>    }<a name="line.394"></a>
+<span class="sourceLineNo">395</span><a name="line.395"></a>
+<span class="sourceLineNo">396</span>  }<a name="line.396"></a>
+<span class="sourceLineNo">397</span><a name="line.397"></a>
+<span class="sourceLineNo">398</span>  /** Helper for Cluster constructor to handle a region */<a name="line.398"></a>
+<span class="sourceLineNo">399</span>  private void registerRegion(RegionInfo region, int regionIndex, int serverIndex,<a name="line.399"></a>
+<span class="sourceLineNo">400</span>    Map&lt;String, Deque&lt;BalancerRegionLoad&gt;&gt; loads, RegionHDFSBlockLocationFinder regionFinder) {<a name="line.400"></a>
+<span class="sourceLineNo">401</span>    String tableName = region.getTable().getNameAsString();<a name="line.401"></a>
+<span class="sourceLineNo">402</span>    if (!tablesToIndex.containsKey(tableName)) {<a name="line.402"></a>
+<span class="sourceLineNo">403</span>      tables.add(tableName);<a name="line.403"></a>
+<span class="sourceLineNo">404</span>      tablesToIndex.put(tableName, tablesToIndex.size());<a name="line.404"></a>
 <span class="sourceLineNo">405</span>    }<a name="line.405"></a>
-<span class="sourceLineNo">406</span>  }<a name="line.406"></a>
+<span class="sourceLineNo">406</span>    int tableIndex = tablesToIndex.get(tableName);<a name="line.406"></a>
 <span class="sourceLineNo">407</span><a name="line.407"></a>
-<span class="sourceLineNo">408</span>  /** Helper for Cluster constructor to handle a region */<a name="line.408"></a>
-<span class="sourceLineNo">409</span>  private void registerRegion(RegionInfo region, int regionIndex, int serverIndex,<a name="line.409"></a>
-<span class="sourceLineNo">410</span>    Map&lt;String, Deque&lt;BalancerRegionLoad&gt;&gt; loads, RegionHDFSBlockLocationFinder regionFinder) {<a name="line.410"></a>
-<span class="sourceLineNo">411</span>    String tableName = region.getTable().getNameAsString();<a name="line.411"></a>
-<span class="sourceLineNo">412</span>    if (!tablesToIndex.containsKey(tableName)) {<a name="line.412"></a>
-<span class="sourceLineNo">413</span>      tables.add(tableName);<a name="line.413"></a>
-<span class="sourceLineNo">414</span>      tablesToIndex.put(tableName, tablesToIndex.size());<a name="line.414"></a>
-<span class="sourceLineNo">415</span>    }<a name="line.415"></a>
-<span class="sourceLineNo">416</span>    int tableIndex = tablesToIndex.get(tableName);<a name="line.416"></a>
-<span class="sourceLineNo">417</span><a name="line.417"></a>
-<span class="sourceLineNo">418</span>    regionsToIndex.put(region, regionIndex);<a name="line.418"></a>
-<span class="sourceLineNo">419</span>    regions[regionIndex] = region;<a name="line.419"></a>
-<span class="sourceLineNo">420</span>    regionIndexToServerIndex[regionIndex] = serverIndex;<a name="line.420"></a>
-<span class="sourceLineNo">421</span>    initialRegionIndexToServerIndex[regionIndex] = serverIndex;<a name="line.421"></a>
-<span class="sourceLineNo">422</span>    regionIndexToTableIndex[regionIndex] = tableIndex;<a name="line.422"></a>
-<span class="sourceLineNo">423</span><a name="line.423"></a>
-<span class="sourceLineNo">424</span>    // region load<a name="line.424"></a>
-<span class="sourceLineNo">425</span>    if (loads != null) {<a name="line.425"></a>
-<span class="sourceLineNo">426</span>      Deque&lt;BalancerRegionLoad&gt; rl = loads.get(region.getRegionNameAsString());<a name="line.426"></a>
-<span class="sourceLineNo">427</span>      // That could have failed if the RegionLoad is using the other regionName<a name="line.427"></a>
-<span class="sourceLineNo">428</span>      if (rl == null) {<a name="line.428"></a>
-<span class="sourceLineNo">429</span>        // Try getting the region load using encoded name.<a name="line.429"></a>
-<span class="sourceLineNo">430</span>        rl = loads.get(region.getEncodedName());<a name="line.430"></a>
-<span class="sourceLineNo">431</span>      }<a name="line.431"></a>
-<span class="sourceLineNo">432</span>      regionLoads[regionIndex] = rl;<a name="line.432"></a>
-<span class="sourceLineNo">433</span>    }<a name="line.433"></a>
-<span class="sourceLineNo">434</span><a name="line.434"></a>
-<span class="sourceLineNo">435</span>    if (regionFinder != null) {<a name="line.435"></a>
-<span class="sourceLineNo">436</span>      // region location<a name="line.436"></a>
-<span class="sourceLineNo">437</span>      List&lt;ServerName&gt; loc = regionFinder.getTopBlockLocations(region);<a name="line.437"></a>
-<span class="sourceLineNo">438</span>      regionLocations[regionIndex] = new int[loc.size()];<a name="line.438"></a>
-<span class="sourceLineNo">439</span>      for (int i = 0; i &lt; loc.size(); i++) {<a name="line.439"></a>
-<span class="sourceLineNo">440</span>        regionLocations[regionIndex][i] = loc.get(i) == null ? -1 :<a name="line.440"></a>
-<span class="sourceLineNo">441</span>          (serversToIndex.get(loc.get(i).getAddress()) == null ? -1 :<a name="line.441"></a>
-<span class="sourceLineNo">442</span>            serversToIndex.get(loc.get(i).getAddress()));<a name="line.442"></a>
-<span class="sourceLineNo">443</span>      }<a name="line.443"></a>
-<span class="sourceLineNo">444</span>    }<a name="line.444"></a>
-<span class="sourceLineNo">445</span>  }<a name="line.445"></a>
-<span class="sourceLineNo">446</span><a name="line.446"></a>
-<span class="sourceLineNo">447</span>  /**<a name="line.447"></a>
-<span class="sourceLineNo">448</span>   * Returns true iff a given server has less regions than the balanced amount<a name="line.448"></a>
+<span class="sourceLineNo">408</span>    regionsToIndex.put(region, regionIndex);<a name="line.408"></a>
+<span class="sourceLineNo">409</span>    regions[regionIndex] = region;<a name="line.409"></a>
+<span class="sourceLineNo">410</span>    regionIndexToServerIndex[regionIndex] = serverIndex;<a name="line.410"></a>
+<span class="sourceLineNo">411</span>    initialRegionIndexToServerIndex[regionIndex] = serverIndex;<a name="line.411"></a>
+<span class="sourceLineNo">412</span>    regionIndexToTableIndex[regionIndex] = tableIndex;<a name="line.412"></a>
+<span class="sourceLineNo">413</span><a name="line.413"></a>
+<span class="sourceLineNo">414</span>    // region load<a name="line.414"></a>
+<span class="sourceLineNo">415</span>    if (loads != null) {<a name="line.415"></a>
+<span class="sourceLineNo">416</span>      Deque&lt;BalancerRegionLoad&gt; rl = loads.get(region.getRegionNameAsString());<a name="line.416"></a>
+<span class="sourceLineNo">417</span>      // That could have failed if the RegionLoad is using the other regionName<a name="line.417"></a>
+<span class="sourceLineNo">418</span>      if (rl == null) {<a name="line.418"></a>
+<span class="sourceLineNo">419</span>        // Try getting the region load using encoded name.<a name="line.419"></a>
+<span class="sourceLineNo">420</span>        rl = loads.get(region.getEncodedName());<a name="line.420"></a>
+<span class="sourceLineNo">421</span>      }<a name="line.421"></a>
+<span class="sourceLineNo">422</span>      regionLoads[regionIndex] = rl;<a name="line.422"></a>
+<span class="sourceLineNo">423</span>    }<a name="line.423"></a>
+<span class="sourceLineNo">424</span><a name="line.424"></a>
+<span class="sourceLineNo">425</span>    if (regionFinder != null) {<a name="line.425"></a>
+<span class="sourceLineNo">426</span>      // region location<a name="line.426"></a>
+<span class="sourceLineNo">427</span>      List&lt;ServerName&gt; loc = regionFinder.getTopBlockLocations(region);<a name="line.427"></a>
+<span class="sourceLineNo">428</span>      regionLocations[regionIndex] = new int[loc.size()];<a name="line.428"></a>
+<span class="sourceLineNo">429</span>      for (int i = 0; i &lt; loc.size(); i++) {<a name="line.429"></a>
+<span class="sourceLineNo">430</span>        regionLocations[regionIndex][i] = loc.get(i) == null ? -1 :<a name="line.430"></a>
+<span class="sourceLineNo">431</span>          (serversToIndex.get(loc.get(i).getAddress()) == null ? -1 :<a name="line.431"></a>
+<span class="sourceLineNo">432</span>            serversToIndex.get(loc.get(i).getAddress()));<a name="line.432"></a>
+<span class="sourceLineNo">433</span>      }<a name="line.433"></a>
+<span class="sourceLineNo">434</span>    }<a name="line.434"></a>
+<span class="sourceLineNo">435</span>  }<a name="line.435"></a>
+<span class="sourceLineNo">436</span><a name="line.436"></a>
+<span class="sourceLineNo">437</span>  /**<a name="line.437"></a>
+<span class="sourceLineNo">438</span>   * Returns true iff a given server has less regions than the balanced amount<a name="line.438"></a>
+<span class="sourceLineNo">439</span>   */<a name="line.439"></a>
+<span class="sourceLineNo">440</span>  public boolean serverHasTooFewRegions(int server) {<a name="line.440"></a>
+<span class="sourceLineNo">441</span>    int minLoad = this.numRegions / numServers;<a name="line.441"></a>
+<span class="sourceLineNo">442</span>    int numRegions = getNumRegions(server);<a name="line.442"></a>
+<span class="sourceLineNo">443</span>    return numRegions &lt; minLoad;<a name="line.443"></a>
+<span class="sourceLineNo">444</span>  }<a name="line.444"></a>
+<span class="sourceLineNo">445</span><a name="line.445"></a>
+<span class="sourceLineNo">446</span>  /**<a name="line.446"></a>
+<span class="sourceLineNo">447</span>   * Retrieves and lazily initializes a field storing the locality of every region/server<a name="line.447"></a>
+<span class="sourceLineNo">448</span>   * combination<a name="line.448"></a>
 <span class="sourceLineNo">449</span>   */<a name="line.449"></a>
-<span class="sourceLineNo">450</span>  public boolean serverHasTooFewRegions(int server) {<a name="line.450"></a>
-<span class="sourceLineNo">451</span>    int minLoad = this.numRegions / numServers;<a name="line.451"></a>
-<span class="sourceLineNo">452</span>    int numRegions = getNumRegions(server);<a name="line.452"></a>
-<span class="sourceLineNo">453</span>    return numRegions &lt; minLoad;<a name="line.453"></a>
-<span class="sourceLineNo">454</span>  }<a name="line.454"></a>
-<span class="sourceLineNo">455</span><a name="line.455"></a>
-<span class="sourceLineNo">456</span>  /**<a name="line.456"></a>
-<span class="sourceLineNo">457</span>   * Retrieves and lazily initializes a field storing the locality of every region/server<a name="line.457"></a>
-<span class="sourceLineNo">458</span>   * combination<a name="line.458"></a>
-<span class="sourceLineNo">459</span>   */<a name="line.459"></a>
-<span class="sourceLineNo">460</span>  public float[][] getOrComputeRackLocalities() {<a name="line.460"></a>
-<span class="sourceLineNo">461</span>    if (rackLocalities == null || regionsToMostLocalEntities == null) {<a name="line.461"></a>
-<span class="sourceLineNo">462</span>      computeCachedLocalities();<a name="line.462"></a>
-<span class="sourceLineNo">463</span>    }<a name="line.463"></a>
-<span class="sourceLineNo">464</span>    return rackLocalities;<a name="line.464"></a>
-<span class="sourceLineNo">465</span>  }<a name="line.465"></a>
-<span class="sourceLineNo">466</span><a name="line.466"></a>
-<span class="sourceLineNo">467</span>  /**<a name="line.467"></a>
-<span class="sourceLineNo">468</span>   * Lazily initializes and retrieves a mapping of region -&gt; server for which region has the highest<a name="line.468"></a>
-<span class="sourceLineNo">469</span>   * the locality<a name="line.469"></a>
+<span class="sourceLineNo">450</span>  public float[][] getOrComputeRackLocalities() {<a name="line.450"></a>
+<span class="sourceLineNo">451</span>    if (rackLocalities == null || regionsToMostLocalEntities == null) {<a name="line.451"></a>
+<span class="sourceLineNo">452</span>      computeCachedLocalities();<a name="line.452"></a>
+<span class="sourceLineNo">453</span>    }<a name="line.453"></a>
+<span class="sourceLineNo">454</span>    return rackLocalities;<a name="line.454"></a>
+<span class="sourceLineNo">455</span>  }<a name="line.455"></a>
+<span class="sourceLineNo">456</span><a name="line.456"></a>
+<span class="sourceLineNo">457</span>  /**<a name="line.457"></a>
+<span class="sourceLineNo">458</span>   * Lazily initializes and retrieves a mapping of region -&gt; server for which region has the highest<a name="line.458"></a>
+<span class="sourceLineNo">459</span>   * the locality<a name="line.459"></a>
+<span class="sourceLineNo">460</span>   */<a name="line.460"></a>
+<span class="sourceLineNo">461</span>  public int[] getOrComputeRegionsToMostLocalEntities(BalancerClusterState.LocalityType type) {<a name="line.461"></a>
+<span class="sourceLineNo">462</span>    if (rackLocalities == null || regionsToMostLocalEntities == null) {<a name="line.462"></a>
+<span class="sourceLineNo">463</span>      computeCachedLocalities();<a name="line.463"></a>
+<span class="sourceLineNo">464</span>    }<a name="line.464"></a>
+<span class="sourceLineNo">465</span>    return regionsToMostLocalEntities[type.ordinal()];<a name="line.465"></a>
+<span class="sourceLineNo">466</span>  }<a name="line.466"></a>
+<span class="sourceLineNo">467</span><a name="line.467"></a>
+<span class="sourceLineNo">468</span>  /**<a name="line.468"></a>
+<span class="sourceLineNo">469</span>   * Looks up locality from cache of localities. Will create cache if it does not already exist.<a name="line.469"></a>
 <span class="sourceLineNo">470</span>   */<a name="line.470"></a>
-<span class="sourceLineNo">471</span>  public int[] getOrComputeRegionsToMostLocalEntities(BalancerClusterState.LocalityType type) {<a name="line.471"></a>
-<span class="sourceLineNo">472</span>    if (rackLocalities == null || regionsToMostLocalEntities == null) {<a name="line.472"></a>
-<span class="sourceLineNo">473</span>      computeCachedLocalities();<a name="line.473"></a>
-<span class="sourceLineNo">474</span>    }<a name="line.474"></a>
-<span class="sourceLineNo">475</span>    return regionsToMostLocalEntities[type.ordinal()];<a name="line.475"></a>
-<span class="sourceLineNo">476</span>  }<a name="line.476"></a>
-<span class="sourceLineNo">477</span><a name="line.477"></a>
-<span class="sourceLineNo">478</span>  /**<a name="line.478"></a>
-<span class="sourceLineNo">479</span>   * Looks up locality from cache of localities. Will create cache if it does not already exist.<a name="line.479"></a>
-<span class="sourceLineNo">480</span>   */<a name="line.480"></a>
-<span class="sourceLineNo">481</span>  public float getOrComputeLocality(int region, int entity,<a name="line.481"></a>
-<span class="sourceLineNo">482</span>    BalancerClusterState.LocalityType type) {<a name="line.482"></a>
-<span class="sourceLineNo">483</span>    switch (type) {<a name="line.483"></a>
-<span class="sourceLineNo">484</span>      case SERVER:<a name="line.484"></a>
-<span class="sourceLineNo">485</span>        return getLocalityOfRegion(region, entity);<a name="line.485"></a>
-<span class="sourceLineNo">486</span>      case RACK:<a name="line.486"></a>
-<span class="sourceLineNo">487</span>        return getOrComputeRackLocalities()[region][entity];<a name="line.487"></a>
-<span class="sourceLineNo">488</span>      default:<a name="line.488"></a>
-<span class="sourceLineNo">489</span>        throw new IllegalArgumentException("Unsupported LocalityType: " + type);<a name="line.489"></a>
-<span class="sourceLineNo">490</span>    }<a name="line.490"></a>
-<span class="sourceLineNo">491</span>  }<a name="line.491"></a>
-<span class="sourceLineNo">492</span><a name="line.492"></a>
-<span class="sourceLineNo">493</span>  /**<a name="line.493"></a>
-<span class="sourceLineNo">494</span>   * Returns locality weighted by region size in MB. Will create locality cache if it does not<a name="line.494"></a>
-<span class="sourceLineNo">495</span>   * already exist.<a name="line.495"></a>
-<span class="sourceLineNo">496</span>   */<a name="line.496"></a>
-<span class="sourceLineNo">497</span>  public double getOrComputeWeightedLocality(int region, int server,<a name="line.497"></a>
-<span class="sourceLineNo">498</span>    BalancerClusterState.LocalityType type) {<a name="line.498"></a>
-<span class="sourceLineNo">499</span>    return getRegionSizeMB(region) * getOrComputeLocality(region, server, type);<a name="line.499"></a>
-<span class="sourceLineNo">500</span>  }<a name="line.500"></a>
-<span class="sourceLineNo">501</span><a name="line.501"></a>
-<span class="sourceLineNo">502</span>  /**<a name="line.502"></a>
-<span class="sourceLineNo">503</span>   * Returns the size in MB from the most recent RegionLoad for region<a name="line.503"></a>
-<span class="sourceLineNo">504</span>   */<a name="line.504"></a>
-<span class="sourceLineNo">505</span>  public int getRegionSizeMB(int region) {<a name="line.505"></a>
-<span class="sourceLineNo">506</span>    Deque&lt;BalancerRegionLoad&gt; load = regionLoads[region];<a name="line.506"></a>
-<span class="sourceLineNo">507</span>    // This means regions have no actual data on disk<a name="line.507"></a>
-<span class="sourceLineNo">508</span>    if (load == null) {<a name="line.508"></a>
-<span class="sourceLineNo">509</span>      return 0;<a name="line.509"></a>
-<span class="sourceLineNo">510</span>    }<a name="line.510"></a>
-<span class="sourceLineNo">511</span>    return regionLoads[region].getLast().getStorefileSizeMB();<a name="line.511"></a>
-<span class="sourceLineNo">512</span>  }<a name="line.512"></a>
-<span class="sourceLineNo">513</span><a name="line.513"></a>
-<span class="sourceLineNo">514</span>  /**<a name="line.514"></a>
-<span class="sourceLineNo">515</span>   * Computes and caches the locality for each region/rack combinations, as well as storing a<a name="line.515"></a>
-<span class="sourceLineNo">516</span>   * mapping of region -&gt; server and region -&gt; rack such that server and rack have the highest<a name="line.516"></a>
-<span class="sourceLineNo">517</span>   * locality for region<a name="line.517"></a>
-<span class="sourceLineNo">518</span>   */<a name="line.518"></a>
-<span class="sourceLineNo">519</span>  private void computeCachedLocalities() {<a name="line.519"></a>
-<span class="sourceLineNo">520</span>    rackLocalities = new float[numRegions][numRacks];<a name="line.520"></a>
-<span class="sourceLineNo">521</span>    regionsToMostLocalEntities = new int[LocalityType.values().length][numRegions];<a name="line.521"></a>
-<span class="sourceLineNo">522</span><a name="line.522"></a>
-<span class="sourceLineNo">523</span>    // Compute localities and find most local server per region<a name="line.523"></a>
-<span class="sourceLineNo">524</span>    for (int region = 0; region &lt; numRegions; region++) {<a name="line.524"></a>
-<span class="sourceLineNo">525</span>      int serverWithBestLocality = 0;<a name="line.525"></a>
-<span class="sourceLineNo">526</span>      float bestLocalityForRegion = 0;<a name="line.526"></a>
-<span class="sourceLineNo">527</span>      for (int server = 0; server &lt; numServers; server++) {<a name="line.527"></a>
-<span class="sourceLineNo">528</span>        // Aggregate per-rack locality<a name="line.528"></a>
-<span class="sourceLineNo">529</span>        float locality = getLocalityOfRegion(region, server);<a name="line.529"></a>
-<span class="sourceLineNo">530</span>        int rack = serverIndexToRackIndex[server];<a name="line.530"></a>
-<span class="sourceLineNo">531</span>        int numServersInRack = serversPerRack[rack].length;<a name="line.531"></a>
-<span class="sourceLineNo">532</span>        rackLocalities[region][rack] += locality / numServersInRack;<a name="line.532"></a>
-<span class="sourceLineNo">533</span><a name="line.533"></a>
-<span class="sourceLineNo">534</span>        if (locality &gt; bestLocalityForRegion) {<a name="line.534"></a>
-<span class="sourceLineNo">535</span>          serverWithBestLocality = server;<a name="line.535"></a>
-<span class="sourceLineNo">536</span>          bestLocalityForRegion = locality;<a name="line.536"></a>
-<span class="sourceLineNo">537</span>        }<a name="line.537"></a>
-<span class="sourceLineNo">538</span>      }<a name="line.538"></a>
-<span class="sourceLineNo">539</span>      regionsToMostLocalEntities[LocalityType.SERVER.ordinal()][region] = serverWithBestLocality;<a name="line.539"></a>
-<span class="sourceLineNo">540</span><a name="line.540"></a>
-<span class="sourceLineNo">541</span>      // Find most local rack per region<a name="line.541"></a>
-<span class="sourceLineNo">542</span>      int rackWithBestLocality = 0;<a name="line.542"></a>
-<span class="sourceLineNo">543</span>      float bestRackLocalityForRegion = 0.0f;<a name="line.543"></a>
-<span class="sourceLineNo">544</span>      for (int rack = 0; rack &lt; numRacks; rack++) {<a name="line.544"></a>
-<span class="sourceLineNo">545</span>        float rackLocality = rackLocalities[region][rack];<a name="line.545"></a>
-<span class="sourceLineNo">546</span>        if (rackLocality &gt; bestRackLocalityForRegion) {<a name="line.546"></a>
-<span class="sourceLineNo">547</span>          bestRackLocalityForRegion = rackLocality;<a name="line.547"></a>
-<span class="sourceLineNo">548</span>          rackWithBestLocality = rack;<a name="line.548"></a>
-<span class="sourceLineNo">549</span>        }<a name="line.549"></a>
-<span class="sourceLineNo">550</span>      }<a name="line.550"></a>
-<span class="sourceLineNo">551</span>      regionsToMostLocalEntities[LocalityType.RACK.ordinal()][region] = rackWithBestLocality;<a name="line.551"></a>
-<span class="sourceLineNo">552</span>    }<a name="line.552"></a>
-<span class="sourceLineNo">553</span><a name="line.553"></a>
-<span class="sourceLineNo">554</span>  }<a name="line.554"></a>
-<span class="sourceLineNo">555</span><a name="line.555"></a>
-<span class="sourceLineNo">556</span>  /**<a name="line.556"></a>
-<span class="sourceLineNo">557</span>   * Maps region index to rack index<a name="line.557"></a>
-<span class="sourceLineNo">558</span>   */<a name="line.558"></a>
-<span class="sourceLineNo">559</span>  public int getRackForRegion(int region) {<a name="line.559"></a>
-<span class="sourceLineNo">560</span>    return serverIndexToRackIndex[regionIndexToServerIndex[region]];<a name="line.560"></a>
-<span class="sourceLineNo">561</span>  }<a name="line.561"></a>
-<span class="sourceLineNo">562</span><a name="line.562"></a>
-<span class="sourceLineNo">563</span>  enum LocalityType {<a name="line.563"></a>
-<span class="sourceLineNo">564</span>    SERVER, RACK<a name="line.564"></a>
-<span class="sourceLineNo">565</span>  }<a name="line.565"></a>
-<span class="sourceLineNo">566</span><a name="line.566"></a>
-<span class="sourceLineNo">567</span>  public void doAction(BalanceAction action) {<a name="line.567"></a>
-<span class="sourceLineNo">568</span>    switch (action.getType()) {<a name="line.568"></a>
-<span class="sourceLineNo">569</span>      case NULL:<a name="line.569"></a>
-<span class="sourceLineNo">570</span>        break;<a name="line.570"></a>
-<span class="sourceLineNo">571</span>      case ASSIGN_REGION:<a name="line.571"></a>
-<span class="sourceLineNo">572</span>        // FindBugs: Having the assert quietens FB BC_UNCONFIRMED_CAST warnings<a name="line.572"></a>
-<span class="sourceLineNo">573</span>        assert action instanceof AssignRegionAction : action.getClass();<a name="line.573"></a>
-<span class="sourceLineNo">574</span>        AssignRegionAction ar = (AssignRegionAction) action;<a name="line.574"></a>
-<span class="sourceLineNo">575</span>        regionsPerServer[ar.getServer()] =<a name="line.575"></a>
-<span class="sourceLineNo">576</span>          addRegion(regionsPerServer[ar.getServer()], ar.getRegion());<a name="line.576"></a>
-<span class="sourceLineNo">577</span>        regionMoved(ar.getRegion(), -1, ar.getServer());<a name="line.577"></a>
-<span class="sourceLineNo">578</span>        break;<a name="line.578"></a>
-<span class="sourceLineNo">579</span>      case MOVE_REGION:<a name="line.579"></a>
-<span class="sourceLineNo">580</span>        assert action instanceof MoveRegionAction : action.getClass();<a name="line.580"></a>
-<span class="sourceLineNo">581</span>        MoveRegionAction mra = (MoveRegionAction) action;<a name="line.581"></a>
-<span class="sourceLineNo">582</span>        regionsPerServer[mra.getFromServer()] =<a name="line.582"></a>
-<span class="sourceLineNo">583</span>          removeRegion(regionsPerServer[mra.getFromServer()], mra.getRegion());<a name="line.583"></a>
-<span class="sourceLineNo">584</span>        regionsPerServer[mra.getToServer()] =<a name="line.584"></a>
-<span class="sourceLineNo">585</span>          addRegion(regionsPerServer[mra.getToServer()], mra.getRegion());<a name="line.585"></a>
-<span class="sourceLineNo">586</span>        regionMoved(mra.getRegion(), mra.getFromServer(), mra.getToServer());<a name="line.586"></a>
+<span class="sourceLineNo">471</span>  public float getOrComputeLocality(int region, int entity,<a name="line.471"></a>
+<span class="sourceLineNo">472</span>    BalancerClusterState.LocalityType type) {<a name="line.472"></a>
+<span class="sourceLineNo">473</span>    switch (type) {<a name="line.473"></a>
+<span class="sourceLineNo">474</span>      case SERVER:<a name="line.474"></a>
+<span class="sourceLineNo">475</span>        return getLocalityOfRegion(region, entity);<a name="line.475"></a>
+<span class="sourceLineNo">476</span>      case RACK:<a name="line.476"></a>
+<span class="sourceLineNo">477</span>        return getOrComputeRackLocalities()[region][entity];<a name="line.477"></a>
+<span class="sourceLineNo">478</span>      default:<a name="line.478"></a>
+<span class="sourceLineNo">479</span>        throw new IllegalArgumentException("Unsupported LocalityType: " + type);<a name="line.479"></a>
+<span class="sourceLineNo">480</span>    }<a name="line.480"></a>
+<span class="sourceLineNo">481</span>  }<a name="line.481"></a>
+<span class="sourceLineNo">482</span><a name="line.482"></a>
+<span class="sourceLineNo">483</span>  /**<a name="line.483"></a>
+<span class="sourceLineNo">484</span>   * Returns locality weighted by region size in MB. Will create locality cache if it does not<a name="line.484"></a>
+<span class="sourceLineNo">485</span>   * already exist.<a name="line.485"></a>
+<span class="sourceLineNo">486</span>   */<a name="line.486"></a>
+<span class="sourceLineNo">487</span>  public double getOrComputeWeightedLocality(int region, int server,<a name="line.487"></a>
+<span class="sourceLineNo">488</span>    BalancerClusterState.LocalityType type) {<a name="line.488"></a>
+<span class="sourceLineNo">489</span>    return getRegionSizeMB(region) * getOrComputeLocality(region, server, type);<a name="line.489"></a>
+<span class="sourceLineNo">490</span>  }<a name="line.490"></a>
+<span class="sourceLineNo">491</span><a name="line.491"></a>
+<span class="sourceLineNo">492</span>  /**<a name="line.492"></a>
+<span class="sourceLineNo">493</span>   * Returns the size in MB from the most recent RegionLoad for region<a name="line.493"></a>
+<span class="sourceLineNo">494</span>   */<a name="line.494"></a>
+<span class="sourceLineNo">495</span>  public int getRegionSizeMB(int region) {<a name="line.495"></a>
+<span class="sourceLineNo">496</span>    Deque&lt;BalancerRegionLoad&gt; load = regionLoads[region];<a name="line.496"></a>
+<span class="sourceLineNo">497</span>    // This means regions have no actual data on disk<a name="line.497"></a>
+<span class="sourceLineNo">498</span>    if (load == null) {<a name="line.498"></a>
+<span class="sourceLineNo">499</span>      return 0;<a name="line.499"></a>
+<span class="sourceLineNo">500</span>    }<a name="line.500"></a>
+<span class="sourceLineNo">501</span>    return regionLoads[region].getLast().getStorefileSizeMB();<a name="line.501"></a>
+<span class="sourceLineNo">502</span>  }<a name="line.502"></a>
+<span class="sourceLineNo">503</span><a name="line.503"></a>
+<span class="sourceLineNo">504</span>  /**<a name="line.504"></a>
+<span class="sourceLineNo">505</span>   * Computes and caches the locality for each region/rack combinations, as well as storing a<a name="line.505"></a>
+<span class="sourceLineNo">506</span>   * mapping of region -&gt; server and region -&gt; rack such that server and rack have the highest<a name="line.506"></a>
+<span class="sourceLineNo">507</span>   * locality for region<a name="line.507"></a>
+<span class="sourceLineNo">508</span>   */<a name="line.508"></a>
+<span class="sourceLineNo">509</span>  private void computeCachedLocalities() {<a name="line.509"></a>
+<span class="sourceLineNo">510</span>    rackLocalities = new float[numRegions][numRacks];<a name="line.510"></a>
+<span class="sourceLineNo">511</span>    regionsToMostLocalEntities = new int[LocalityType.values().length][numRegions];<a name="line.511"></a>
+<span class="sourceLineNo">512</span><a name="line.512"></a>
+<span class="sourceLineNo">513</span>    // Compute localities and find most local server per region<a name="line.513"></a>
+<span class="sourceLineNo">514</span>    for (int region = 0; region &lt; numRegions; region++) {<a name="line.514"></a>
+<span class="sourceLineNo">515</span>      int serverWithBestLocality = 0;<a name="line.515"></a>
+<span class="sourceLineNo">516</span>      float bestLocalityForRegion = 0;<a name="line.516"></a>
+<span class="sourceLineNo">517</span>      for (int server = 0; server &lt; numServers; server++) {<a name="line.517"></a>
+<span class="sourceLineNo">518</span>        // Aggregate per-rack locality<a name="line.518"></a>
+<span class="sourceLineNo">519</span>        float locality = getLocalityOfRegion(region, server);<a name="line.519"></a>
+<span class="sourceLineNo">520</span>        int rack = serverIndexToRackIndex[server];<a name="line.520"></a>
+<span class="sourceLineNo">521</span>        int numServersInRack = serversPerRack[rack].length;<a name="line.521"></a>
+<span class="sourceLineNo">522</span>        rackLocalities[region][rack] += locality / numServersInRack;<a name="line.522"></a>
+<span class="sourceLineNo">523</span><a name="line.523"></a>
+<span class="sourceLineNo">524</span>        if (locality &gt; bestLocalityForRegion) {<a name="line.524"></a>
+<span class="sourceLineNo">525</span>          serverWithBestLocality = server;<a name="line.525"></a>
+<span class="sourceLineNo">526</span>          bestLocalityForRegion = locality;<a name="line.526"></a>
+<span class="sourceLineNo">527</span>        }<a name="line.527"></a>
+<span class="sourceLineNo">528</span>      }<a name="line.528"></a>
+<span class="sourceLineNo">529</span>      regionsToMostLocalEntities[LocalityType.SERVER.ordinal()][region] = serverWithBestLocality;<a name="line.529"></a>
+<span class="sourceLineNo">530</span><a name="line.530"></a>
+<span class="sourceLineNo">531</span>      // Find most local rack per region<a name="line.531"></a>
+<span class="sourceLineNo">532</span>      int rackWithBestLocality = 0;<a name="line.532"></a>
+<span class="sourceLineNo">533</span>      float bestRackLocalityForRegion = 0.0f;<a name="line.533"></a>
+<span class="sourceLineNo">534</span>      for (int rack = 0; rack &lt; numRacks; rack++) {<a name="line.534"></a>
+<span class="sourceLineNo">535</span>        float rackLocality = rackLocalities[region][rack];<a name="line.535"></a>
+<span class="sourceLineNo">536</span>        if (rackLocality &gt; bestRackLocalityForRegion) {<a name="line.536"></a>
+<span class="sourceLineNo">537</span>          bestRackLocalityForRegion = rackLocality;<a name="line.537"></a>
+<span class="sourceLineNo">538</span>          rackWithBestLocality = rack;<a name="line.538"></a>
+<span class="sourceLineNo">539</span>        }<a name="line.539"></a>
+<span class="sourceLineNo">540</span>      }<a name="line.540"></a>
+<span class="sourceLineNo">541</span>      regionsToMostLocalEntities[LocalityType.RACK.ordinal()][region] = rackWithBestLocality;<a name="line.541"></a>
+<span class="sourceLineNo">542</span>    }<a name="line.542"></a>
+<span class="sourceLineNo">543</span><a name="line.543"></a>
+<span class="sourceLineNo">544</span>  }<a name="line.544"></a>
+<span class="sourceLineNo">545</span><a name="line.545"></a>
+<span class="sourceLineNo">546</span>  /**<a name="line.546"></a>
+<span class="sourceLineNo">547</span>   * Maps region index to rack index<a name="line.547"></a>
+<span class="sourceLineNo">548</span>   */<a name="line.548"></a>
+<span class="sourceLineNo">549</span>  public int getRackForRegion(int region) {<a name="line.549"></a>
+<span class="sourceLineNo">550</span>    return serverIndexToRackIndex[regionIndexToServerIndex[region]];<a name="line.550"></a>
+<span class="sourceLineNo">551</span>  }<a name="line.551"></a>
+<span class="sourceLineNo">552</span><a name="line.552"></a>
+<span class="sourceLineNo">553</span>  enum LocalityType {<a name="line.553"></a>
+<span class="sourceLineNo">554</span>    SERVER, RACK<a name="line.554"></a>
+<span class="sourceLineNo">555</span>  }<a name="line.555"></a>
+<span class="sourceLineNo">556</span><a name="line.556"></a>
+<span class="sourceLineNo">557</span>  public void doAction(BalanceAction action) {<a name="line.557"></a>
+<span class="sourceLineNo">558</span>    switch (action.getType()) {<a name="line.558"></a>
+<span class="sourceLineNo">559</span>      case NULL:<a name="line.559"></a>
+<span class="sourceLineNo">560</span>        break;<a name="line.560"></a>
+<span class="sourceLineNo">561</span>      case ASSIGN_REGION:<a name="line.561"></a>
+<span class="sourceLineNo">562</span>        // FindBugs: Having the assert quietens FB BC_UNCONFIRMED_CAST warnings<a name="line.562"></a>
+<span class="sourceLineNo">563</span>        assert action instanceof AssignRegionAction : action.getClass();<a name="line.563"></a>
+<span class="sourceLineNo">564</span>        AssignRegionAction ar = (AssignRegionAction) action;<a name="line.564"></a>
+<span class="sourceLineNo">565</span>        regionsPerServer[ar.getServer()] =<a name="line.565"></a>
+<span class="sourceLineNo">566</span>          addRegion(regionsPerServer[ar.getServer()], ar.getRegion());<a name="line.566"></a>
+<span class="sourceLineNo">567</span>        regionMoved(ar.getRegion(), -1, ar.getServer());<a name="line.567"></a>
+<span class="sourceLineNo">568</span>        break;<a name="line.568"></a>
+<span class="sourceLineNo">569</span>      case MOVE_REGION:<a name="line.569"></a>
+<span class="sourceLineNo">570</span>        assert action instanceof MoveRegionAction : action.getClass();<a name="line.570"></a>
+<span class="sourceLineNo">571</span>        MoveRegionAction mra = (MoveRegionAction) action;<a name="line.571"></a>
+<span class="sourceLineNo">572</span>        regionsPerServer[mra.getFromServer()] =<a name="line.572"></a>
+<span class="sourceLineNo">573</span>          removeRegion(regionsPerServer[mra.getFromServer()], mra.getRegion());<a name="line.573"></a>
+<span class="sourceLineNo">574</span>        regionsPerServer[mra.getToServer()] =<a name="line.574"></a>
+<span class="sourceLineNo">575</span>          addRegion(regionsPerServer[mra.getToServer()], mra.getRegion());<a name="line.575"></a>
+<span class="sourceLineNo">576</span>        regionMoved(mra.getRegion(), mra.getFromServer(), mra.getToServer());<a name="line.576"></a>
+<span class="sourceLineNo">577</span>        break;<a name="line.577"></a>
+<span class="sourceLineNo">578</span>      case SWAP_REGIONS:<a name="line.578"></a>
+<span class="sourceLineNo">579</span>        assert action instanceof SwapRegionsAction : action.getClass();<a name="line.579"></a>
+<span class="sourceLineNo">580</span>        SwapRegionsAction a = (SwapRegionsAction) action;<a name="line.580"></a>
+<span class="sourceLineNo">581</span>        regionsPerServer[a.getFromServer()] =<a name="line.581"></a>
+<span class="sourceLineNo">582</span>          replaceRegion(regionsPerServer[a.getFromServer()], a.getFromRegion(), a.getToRegion());<a name="line.582"></a>
+<span class="sourceLineNo">583</span>        regionsPerServer[a.getToServer()] =<a name="line.583"></a>
+<span class="sourceLineNo">584</span>          replaceRegion(regionsPerServer[a.getToServer()], a.getToRegion(), a.getFromRegion());<a name="line.584"></a>
+<span class="sourceLineNo">585</span>        regionMoved(a.getFromRegion(), a.getFromServer(), a.getToServer());<a name="line.585"></a>
+<span class="sourceLineNo">586</span>        regionMoved(a.getToRegion(), a.getToServer(), a.getFromServer());<a name="line.586"></a>
 <span class="sourceLineNo">587</span>        break;<a name="line.587"></a>
-<span class="sourceLineNo">588</span>      case SWAP_REGIONS:<a name="line.588"></a>
-<span class="sourceLineNo">589</span>        assert action instanceof SwapRegionsAction : action.getClass();<a name="line.589"></a>
-<span class="sourceLineNo">590</span>        SwapRegionsAction a = (SwapRegionsAction) action;<a name="line.590"></a>
-<span class="sourceLineNo">591</span>        regionsPerServer[a.getFromServer()] =<a name="line.591"></a>
-<span class="sourceLineNo">592</span>          replaceRegion(regionsPerServer[a.getFromServer()], a.getFromRegion(), a.getToRegion());<a name="line.592"></a>
-<span class="sourceLineNo">593</span>        regionsPerServer[a.getToServer()] =<a name="line.593"></a>
-<span class="sourceLineNo">594</span>          replaceRegion(regionsPerServer[a.getToServer()], a.getToRegion(), a.getFromRegion());<a name="line.594"></a>
-<span class="sourceLineNo">595</span>        regionMoved(a.getFromRegion(), a.getFromServer(), a.getToServer());<a name="line.595"></a>
-<span class="sourceLineNo">596</span>        regionMoved(a.getToRegion(), a.getToServer(), a.getFromServer());<a name="line.596"></a>
-<span class="sourceLineNo">597</span>        break;<a name="line.597"></a>
-<span class="sourceLineNo">598</span>      default:<a name="line.598"></a>
-<span class="sourceLineNo">599</span>        throw new RuntimeException("Uknown action:" + action.getType());<a name="line.599"></a>
-<span class="sourceLineNo">600</span>    }<a name="line.600"></a>
-<span class="sourceLineNo">601</span>  }<a name="line.601"></a>
-<span class="sourceLineNo">602</span><a name="line.602"></a>
-<span class="sourceLineNo">603</span>  /**<a name="line.603"></a>
-<span class="sourceLineNo">604</span>   * Return true if the placement of region on server would lower the availability of the region in<a name="line.604"></a>
-<span class="sourceLineNo">605</span>   * question<a name="line.605"></a>
-<span class="sourceLineNo">606</span>   * @return true or false<a name="line.606"></a>
-<span class="sourceLineNo">607</span>   */<a name="line.607"></a>
-<span class="sourceLineNo">608</span>  boolean wouldLowerAvailability(RegionInfo regionInfo, ServerName serverName) {<a name="line.608"></a>
-<span class="sourceLineNo">609</span>    if (!serversToIndex.containsKey(serverName.getAddress())) {<a name="line.609"></a>
-<span class="sourceLineNo">610</span>      return false; // safeguard against race between cluster.servers and servers from LB method<a name="line.610"></a>
-<span class="sourceLineNo">611</span>                    // args<a name="line.611"></a>
+<span class="sourceLineNo">588</span>      default:<a name="line.588"></a>
+<span class="sourceLineNo">589</span>        throw new RuntimeException("Uknown action:" + action.getType());<a name="line.589"></a>
+<span class="sourceLineNo">590</span>    }<a name="line.590"></a>
+<span class="sourceLineNo">591</span>  }<a name="line.591"></a>
+<span class="sourceLineNo">592</span><a name="line.592"></a>
+<span class="sourceLineNo">593</span>  /**<a name="line.593"></a>
+<span class="sourceLineNo">594</span>   * Return true if the placement of region on server would lower the availability of the region in<a name="line.594"></a>
+<span class="sourceLineNo">595</span>   * question<a name="line.595"></a>
+<span class="sourceLineNo">596</span>   * @return true or false<a name="line.596"></a>
+<span class="sourceLineNo">597</span>   */<a name="line.597"></a>
+<span class="sourceLineNo">598</span>  boolean wouldLowerAvailability(RegionInfo regionInfo, ServerName serverName) {<a name="line.598"></a>
+<span class="sourceLineNo">599</span>    if (!serversToIndex.containsKey(serverName.getAddress())) {<a name="line.599"></a>
+<span class="sourceLineNo">600</span>      return false; // safeguard against race between cluster.servers and servers from LB method<a name="line.600"></a>
+<span class="sourceLineNo">601</span>      // args<a name="line.601"></a>
+<span class="sourceLineNo">602</span>    }<a name="line.602"></a>
+<span class="sourceLineNo">603</span>    int server = serversToIndex.get(serverName.getAddress());<a name="line.603"></a>
+<span class="sourceLineNo">604</span>    int region = regionsToIndex.get(regionInfo);<a name="line.604"></a>
+<span class="sourceLineNo">605</span><a name="line.605"></a>
+<span class="sourceLineNo">606</span>    // Region replicas for same region should better assign to different servers<a name="line.606"></a>
+<span class="sourceLineNo">607</span>    for (int i : regionsPerServer[server]) {<a name="line.607"></a>
+<span class="sourceLineNo">608</span>      RegionInfo otherRegionInfo = regions[i];<a name="line.608"></a>
+<span class="sourceLineNo">609</span>      if (RegionReplicaUtil.isReplicasForSameRegion(regionInfo, otherRegionInfo)) {<a name="line.609"></a>
+<span class="sourceLineNo">610</span>        return true;<a name="line.610"></a>
+<span class="sourceLineNo">611</span>      }<a name="line.611"></a>
 <span class="sourceLineNo">612</span>    }<a name="line.612"></a>
-<span class="sourceLineNo">613</span>    int server = serversToIndex.get(serverName.getAddress());<a name="line.613"></a>
-<span class="sourceLineNo">614</span>    int region = regionsToIndex.get(regionInfo);<a name="line.614"></a>
-<span class="sourceLineNo">615</span><a name="line.615"></a>
-<span class="sourceLineNo">616</span>    // Region replicas for same region should better assign to different servers<a name="line.616"></a>
-<span class="sourceLineNo">617</span>    for (int i : regionsPerServer[server]) {<a name="line.617"></a>
-<span class="sourceLineNo">618</span>      RegionInfo otherRegionInfo = regions[i];<a name="line.618"></a>
-<span class="sourceLineNo">619</span>      if (RegionReplicaUtil.isReplicasForSameRegion(regionInfo, otherRegionInfo)) {<a name="line.619"></a>
-<span class="sourceLineNo">620</span>        return true;<a name="line.620"></a>
-<span class="sourceLineNo">621</span>      }<a name="line.621"></a>
-<span class="sourceLineNo">622</span>    }<a name="line.622"></a>
-<span class="sourceLineNo">623</span><a name="line.623"></a>
-<span class="sourceLineNo">624</span>    int primary = regionIndexToPrimaryIndex[region];<a name="line.624"></a>
-<span class="sourceLineNo">625</span>    if (primary == -1) {<a name="line.625"></a>
-<span class="sourceLineNo">626</span>      return false;<a name="line.626"></a>
-<span class="sourceLineNo">627</span>    }<a name="line.627"></a>
-<span class="sourceLineNo">628</span>    // there is a subset relation for server &lt; host &lt; rack<a name="line.628"></a>
-<span class="sourceLineNo">629</span>    // check server first<a name="line.629"></a>
-<span class="sourceLineNo">630</span>    if (contains(primariesOfRegionsPerServer[server], primary)) {<a name="line.630"></a>
-<span class="sourceLineNo">631</span>      // check for whether there are other servers that we can place this region<a name="line.631"></a>
-<span class="sourceLineNo">632</span>      for (int i = 0; i &lt; primariesOfRegionsPerServer.length; i++) {<a name="line.632"></a>
-<span class="sourceLineNo">633</span>        if (i != server &amp;&amp; !contains(primariesOfRegionsPerServer[i], primary)) {<a name="line.633"></a>
-<span class="sourceLineNo">634</span>          return true; // meaning there is a better server<a name="line.634"></a>
-<span class="sourceLineNo">635</span>        }<a name="line.635"></a>
-<span class="sourceLineNo">636</span>      }<a name="line.636"></a>
-<span class="sourceLineNo">637</span>      return false; // there is not a better server to place this<a name="line.637"></a>
-<span class="sourceLineNo">638</span>    }<a name="line.638"></a>
-<span class="sourceLineNo">639</span><a name="line.639"></a>
-<span class="sourceLineNo">640</span>    // check host<a name="line.640"></a>
-<span class="sourceLineNo">641</span>    if (multiServersPerHost) {<a name="line.641"></a>
-<span class="sourceLineNo">642</span>      // these arrays would only be allocated if we have more than one server per host<a name="line.642"></a>
-<span class="sourceLineNo">643</span>      int host = serverIndexToHostIndex[server];<a name="line.643"></a>
-<span class="sourceLineNo">644</span>      if (contains(primariesOfRegionsPerHost[host], primary)) {<a name="line.644"></a>
-<span class="sourceLineNo">645</span>        // check for whether there are other hosts that we can place this region<a name="line.645"></a>
-<span class="sourceLineNo">646</span>        for (int i = 0; i &lt; primariesOfRegionsPerHost.length; i++) {<a name="line.646"></a>
-<span class="sourceLineNo">647</span>          if (i != host &amp;&amp; !contains(primariesOfRegionsPerHost[i], primary)) {<a name="line.647"></a>
-<span class="sourceLineNo">648</span>            return true; // meaning there is a better host<a name="line.648"></a>
-<span class="sourceLineNo">649</span>          }<a name="line.649"></a>
-<span class="sourceLineNo">650</span>        }<a name="line.650"></a>
-<span class="sourceLineNo">651</span>        return false; // there is not a better host to place this<a name="line.651"></a>
-<span class="sourceLineNo">652</span>      }<a name="line.652"></a>
-<span class="sourceLineNo">653</span>    }<a name="line.653"></a>
-<span class="sourceLineNo">654</span><a name="line.654"></a>
-<span class="sourceLineNo">655</span>    // check rack<a name="line.655"></a>
-<span class="sourceLineNo">656</span>    if (numRacks &gt; 1) {<a name="line.656"></a>
-<span class="sourceLineNo">657</span>      int rack = serverIndexToRackIndex[server];<a name="line.657"></a>
-<span class="sourceLineNo">658</span>      if (contains(primariesOfRegionsPerRack[rack], primary)) {<a name="line.658"></a>
-<span class="sourceLineNo">659</span>        // check for whether there are other racks that we can place this region<a name="line.659"></a>
-<span class="sourceLineNo">660</span>        for (int i = 0; i &lt; primariesOfRegionsPerRack.length; i++) {<a name="line.660"></a>
-<span class="sourceLineNo">661</span>          if (i != rack &amp;&amp; !contains(primariesOfRegionsPerRack[i], primary)) {<a name="line.661"></a>
-<span class="sourceLineNo">662</span>            return true; // meaning there is a better rack<a name="line.662"></a>
-<span class="sourceLineNo">663</span>          }<a name="line.663"></a>
-<span class="sourceLineNo">664</span>        }<a name="line.664"></a>
-<span class="sourceLineNo">665</span>        return false; // there is not a better rack to place this<a name="line.665"></a>
-<span class="sourceLineNo">666</span>      }<a name="line.666"></a>
-<span class="sourceLineNo">667</span>    }<a name="line.667"></a>
-<span class="sourceLineNo">668</span><a name="line.668"></a>
-<span class="sourceLineNo">669</span>    return false;<a name="line.669"></a>
-<span class="sourceLineNo">670</span>  }<a name="line.670"></a>
-<span class="sourceLineNo">671</span><a name="line.671"></a>
-<span class="sourceLineNo">672</span>  void doAssignRegion(RegionInfo regionInfo, ServerName serverName) {<a name="line.672"></a>
-<span class="sourceLineNo">673</span>    if (!serversToIndex.containsKey(serverName.getAddress())) {<a name="line.673"></a>
-<span class="sourceLineNo">674</span>      return;<a name="line.674"></a>
-<span class="sourceLineNo">675</span>    }<a name="line.675"></a>
-<span class="sourceLineNo">676</span>    int server = serversToIndex.get(serverName.getAddress());<a name="line.676"></a>
-<span class="sourceLineNo">677</span>    int region = regionsToIndex.get(regionInfo);<a name="line.677"></a>
-<span class="sourceLineNo">678</span>    doAction(new AssignRegionAction(region, server));<a name="line.678"></a>
-<span class="sourceLineNo">679</span>  }<a name="line.679"></a>
-<span class="sourceLineNo">680</span><a name="line.680"></a>
-<span class="sourceLineNo">681</span>  void regionMoved(int region, int oldServer, int newServer) {<a name="line.681"></a>
-<span class="sourceLineNo">682</span>    regionIndexToServerIndex[region] = newServer;<a name="line.682"></a>
-<span class="sourceLineNo">683</span>    if (initialRegionIndexToServerIndex[region] == newServer) {<a name="line.683"></a>
-<span class="sourceLineNo">684</span>      numMovedRegions--; // region moved back to original location<a name="line.684"></a>
-<span class="sourceLineNo">685</span>    } else if (oldServer &gt;= 0 &amp;&amp; initialRegionIndexToServerIndex[region] == oldServer) {<a name="line.685"></a>
-<span class="sourceLineNo">686</span>      numMovedRegions++; // region moved from original location<a name="line.686"></a>
-<span class="sourceLineNo">687</span>    }<a name="line.687"></a>
-<span class="sourceLineNo">688</span>    int tableIndex = regionIndexToTableIndex[region];<a name="line.688"></a>
-<span class="sourceLineNo">689</span>    if (oldServer &gt;= 0) {<a name="line.689"></a>
-<span class="sourceLineNo">690</span>      numRegionsPerServerPerTable[oldServer][tableIndex]--;<a name="line.690"></a>
-<span class="sourceLineNo">691</span>      // update regionSkewPerTable for the move from old server<a name="line.691"></a>
-<span class="sourceLineNo">692</span>      regionSkewByTable[tableIndex] += getSkewChangeFor(oldServer, tableIndex, -1);<a name="line.692"></a>
-<span class="sourceLineNo">693</span>    }<a name="line.693"></a>
-<span class="sourceLineNo">694</span>    numRegionsPerServerPerTable[newServer][tableIndex]++;<a name="line.694"></a>
-<span class="sourceLineNo">695</span><a name="line.695"></a>
-<span class="sourceLineNo">696</span>    // update regionSkewPerTable for the move to new server<a name="line.696"></a>
-<span class="sourceLineNo">697</span>    regionSkewByTable[tableIndex] += getSkewChangeFor(newServer, tableIndex, 1);<a name="line.697"></a>
+<span class="sourceLineNo">613</span><a name="line.613"></a>
+<span class="sourceLineNo">614</span>    int primary = regionIndexToPrimaryIndex[region];<a name="line.614"></a>
+<span class="sourceLineNo">615</span>    if (primary == -1) {<a name="line.615"></a>
+<span class="sourceLineNo">616</span>      return false;<a name="line.616"></a>
+<span class="sourceLineNo">617</span>    }<a name="line.617"></a>
+<span class="sourceLineNo">618</span>    // there is a subset relation for server &lt; host &lt; rack<a name="line.618"></a>
+<span class="sourceLineNo">619</span>    // check server first<a name="line.619"></a>
+<span class="sourceLineNo">620</span>    int result = checkLocationForPrimary(server, colocatedReplicaCountsPerServer, primary);<a name="line.620"></a>
+<span class="sourceLineNo">621</span>    if (result != 0) {<a name="line.621"></a>
+<span class="sourceLineNo">622</span>      return result &gt; 0;<a name="line.622"></a>
+<span class="sourceLineNo">623</span>    }<a name="line.623"></a>
+<span class="sourceLineNo">624</span><a name="line.624"></a>
+<span class="sourceLineNo">625</span>    // check host<a name="line.625"></a>
+<span class="sourceLineNo">626</span>    if (multiServersPerHost) {<a name="line.626"></a>
+<span class="sourceLineNo">627</span>      result = checkLocationForPrimary(serverIndexToHostIndex[server],<a name="line.627"></a>
+<span class="sourceLineNo">628</span>        colocatedReplicaCountsPerHost, primary);<a name="line.628"></a>
+<span class="sourceLineNo">629</span>      if (result != 0) {<a name="line.629"></a>
+<span class="sourceLineNo">630</span>        return result &gt; 0;<a name="line.630"></a>
+<span class="sourceLineNo">631</span>      }<a name="line.631"></a>
+<span class="sourceLineNo">632</span>    }<a name="line.632"></a>
+<span class="sourceLineNo">633</span><a name="line.633"></a>
+<span class="sourceLineNo">634</span>    // check rack<a name="line.634"></a>
+<span class="sourceLineNo">635</span>    if (numRacks &gt; 1) {<a name="line.635"></a>
+<span class="sourceLineNo">636</span>      result = checkLocationForPrimary(serverIndexToRackIndex[server],<a name="line.636"></a>
+<span class="sourceLineNo">637</span>        colocatedReplicaCountsPerRack, primary);<a name="line.637"></a>
+<span class="sourceLineNo">638</span>      if (result != 0) {<a name="line.638"></a>
+<span class="sourceLineNo">639</span>        return result &gt; 0;<a name="line.639"></a>
+<span class="sourceLineNo">640</span>      }<a name="line.640"></a>
+<span class="sourceLineNo">641</span>    }<a name="line.641"></a>
+<span class="sourceLineNo">642</span>    return false;<a name="line.642"></a>
+<span class="sourceLineNo">643</span>  }<a name="line.643"></a>
+<span class="sourceLineNo">644</span><a name="line.644"></a>
+<span class="sourceLineNo">645</span>  /**<a name="line.645"></a>
+<span class="sourceLineNo">646</span>   * Common method for better solution check.<a name="line.646"></a>
+<span class="sourceLineNo">647</span>   * @param colocatedReplicaCountsPerLocation colocatedReplicaCountsPerHost or<a name="line.647"></a>
+<span class="sourceLineNo">648</span>   *                                          colocatedReplicaCountsPerRack<a name="line.648"></a>
+<span class="sourceLineNo">649</span>   * @return 1 for better, -1 for no better, 0 for unknown<a name="line.649"></a>
+<span class="sourceLineNo">650</span>   */<a name="line.650"></a>
+<span class="sourceLineNo">651</span>  private int checkLocationForPrimary(int location,<a name="line.651"></a>
+<span class="sourceLineNo">652</span>    Int2IntCounterMap[] colocatedReplicaCountsPerLocation, int primary) {<a name="line.652"></a>
+<span class="sourceLineNo">653</span>    if (colocatedReplicaCountsPerLocation[location].containsKey(primary)) {<a name="line.653"></a>
+<span class="sourceLineNo">654</span>      // check for whether there are other Locations that we can place this region<a name="line.654"></a>
+<span class="sourceLineNo">655</span>      for (int i = 0; i &lt; colocatedReplicaCountsPerLocation.length; i++) {<a name="line.655"></a>
+<span class="sourceLineNo">656</span>        if (i != location &amp;&amp; !colocatedReplicaCountsPerLocation[i].containsKey(primary)) {<a name="line.656"></a>
+<span class="sourceLineNo">657</span>          return 1; // meaning there is a better Location<a name="line.657"></a>
+<span class="sourceLineNo">658</span>        }<a name="line.658"></a>
+<span class="sourceLineNo">659</span>      }<a name="line.659"></a>
+<span class="sourceLineNo">660</span>      return -1; // there is not a better Location to place this<a name="line.660"></a>
+<span class="sourceLineNo">661</span>    }<a name="line.661"></a>
+<span class="sourceLineNo">662</span>    return 0;<a name="line.662"></a>
+<span class="sourceLineNo">663</span>  }<a name="line.663"></a>
+<span class="sourceLineNo">664</span><a name="line.664"></a>
+<span class="sourceLineNo">665</span>  void doAssignRegion(RegionInfo regionInfo, ServerName serverName) {<a name="line.665"></a>
+<span class="sourceLineNo">666</span>    if (!serversToIndex.containsKey(serverName.getAddress())) {<a name="line.666"></a>
+<span class="sourceLineNo">667</span>      return;<a name="line.667"></a>
+<span class="sourceLineNo">668</span>    }<a name="line.668"></a>
+<span class="sourceLineNo">669</span>    int server = serversToIndex.get(serverName.getAddress());<a name="line.669"></a>
+<span class="sourceLineNo">670</span>    int region = regionsToIndex.get(regionInfo);<a name="line.670"></a>
+<span class="sourceLineNo">671</span>    doAction(new AssignRegionAction(region, server));<a name="line.671"></a>
+<span class="sourceLineNo">672</span>  }<a name="line.672"></a>
+<span class="sourceLineNo">673</span><a name="line.673"></a>
+<span class="sourceLineNo">674</span>  void regionMoved(int region, int oldServer, int newServer) {<a name="line.674"></a>
+<span class="sourceLineNo">675</span>    regionIndexToServerIndex[region] = newServer;<a name="line.675"></a>
+<span class="sourceLineNo">676</span>    if (initialRegionIndexToServerIndex[region] == newServer) {<a name="line.676"></a>
+<span class="sourceLineNo">677</span>      numMovedRegions--; // region moved back to original location<a name="line.677"></a>
+<span class="sourceLineNo">678</span>    } else if (oldServer &gt;= 0 &amp;&amp; initialRegionIndexToServerIndex[region] == oldServer) {<a name="line.678"></a>
+<span class="sourceLineNo">679</span>      numMovedRegions++; // region moved from original location<a name="line.679"></a>
+<span class="sourceLineNo">680</span>    }<a name="line.680"></a>
+<span class="sourceLineNo">681</span>    int tableIndex = regionIndexToTableIndex[region];<a name="line.681"></a>
+<span class="sourceLineNo">682</span>    if (oldServer &gt;= 0) {<a name="line.682"></a>
+<span class="sourceLineNo">683</span>      numRegionsPerServerPerTable[oldServer][tableIndex]--;<a name="line.683"></a>
+<span class="sourceLineNo">684</span>      // update regionSkewPerTable for the move from old server<a name="line.684"></a>
+<span class="sourceLineNo">685</span>      regionSkewByTable[tableIndex] += getSkewChangeFor(oldServer, tableIndex, -1);<a name="line.685"></a>
+<span class="sourceLineNo">686</span>    }<a name="line.686"></a>
+<span class="sourceLineNo">687</span>    numRegionsPerServerPerTable[newServer][tableIndex]++;<a name="line.687"></a>
+<span class="sourceLineNo">688</span><a name="line.688"></a>
+<span class="sourceLineNo">689</span>    // update regionSkewPerTable for the move to new server<a name="line.689"></a>
+<span class="sourceLineNo">690</span>    regionSkewByTable[tableIndex] += getSkewChangeFor(newServer, tableIndex, 1);<a name="line.690"></a>
+<span class="sourceLineNo">691</span><a name="line.691"></a>
+<span class="sourceLineNo">692</span>    // update for servers<a name="line.692"></a>
+<span class="sourceLineNo">693</span>    int primary = regionIndexToPrimaryIndex[region];<a name="line.693"></a>
+<span class="sourceLineNo">694</span>    if (oldServer &gt;= 0) {<a name="line.694"></a>
+<span class="sourceLineNo">695</span>      colocatedReplicaCountsPerServer[oldServer].getAndDecrement(primary);<a name="line.695"></a>
+<span class="sourceLineNo">696</span>    }<a name="line.696"></a>
+<span class="sourceLineNo">697</span>    colocatedReplicaCountsPerServer[newServer].getAndIncrement(primary);<a name="line.697"></a>
 <span class="sourceLineNo">698</span><a name="line.698"></a>
-<span class="sourceLineNo">699</span>    // update for servers<a name="line.699"></a>
-<span class="sourceLineNo">700</span>    int primary = regionIndexToPrimaryIndex[region];<a name="line.700"></a>
-<span class="sourceLineNo">701</span>    if (oldServer &gt;= 0) {<a name="line.701"></a>
-<span class="sourceLineNo">702</span>      primariesOfRegionsPerServer[oldServer] =<a name="line.702"></a>
-<span class="sourceLineNo">703</span>        removeRegion(primariesOfRegionsPerServer[oldServer], primary);<a name="line.703"></a>
-<span class="sourceLineNo">704</span>    }<a name="line.704"></a>
-<span class="sourceLineNo">705</span>    primariesOfRegionsPerServer[newServer] =<a name="line.705"></a>
-<span class="sourceLineNo">706</span>      addRegionSorted(primariesOfRegionsPerServer[newServer], primary);<a name="line.706"></a>
-<span class="sourceLineNo">707</span><a name="line.707"></a>
-<span class="sourceLineNo">708</span>    // update for hosts<a name="line.708"></a>
-<span class="sourceLineNo">709</span>    if (multiServersPerHost) {<a name="line.709"></a>
-<span class="sourceLineNo">710</span>      int oldHost = oldServer &gt;= 0 ? serverIndexToHostIndex[oldServer] : -1;<a name="line.710"></a>
-<span class="sourceLineNo">711</span>      int newHost = serverIndexToHostIndex[newServer];<a name="line.711"></a>
-<span class="sourceLineNo">712</span>      if (newHost != oldHost) {<a name="line.712"></a>
-<span class="sourceLineNo">713</span>        regionsPerHost[newHost] = addRegion(regionsPerHost[newHost], region);<a name="line.713"></a>
-<span class="sourceLineNo">714</span>        primariesOfRegionsPerHost[newHost] =<a name="line.714"></a>
-<span class="sourceLineNo">715</span>          addRegionSorted(primariesOfRegionsPerHost[newHost], primary);<a name="line.715"></a>
-<span class="sourceLineNo">716</span>        if (oldHost &gt;= 0) {<a name="line.716"></a>
-<span class="sourceLineNo">717</span>          regionsPerHost[oldHost] = removeRegion(regionsPerHost[oldHost], region);<a name="line.717"></a>
-<span class="sourceLineNo">718</span>          primariesOfRegionsPerHost[oldHost] =<a name="line.718"></a>
-<span class="sourceLineNo">719</span>            removeRegion(primariesOfRegionsPerHost[oldHost], primary); // will still be sorted<a name="line.719"></a>
-<span class="sourceLineNo">720</span>        }<a name="line.720"></a>
-<span class="sourceLineNo">721</span>      }<a name="line.721"></a>
-<span class="sourceLineNo">722</span>    }<a name="line.722"></a>
-<span class="sourceLineNo">723</span><a name="line.723"></a>
-<span class="sourceLineNo">724</span>    // update for racks<a name="line.724"></a>
-<span class="sourceLineNo">725</span>    if (numRacks &gt; 1) {<a name="line.725"></a>
-<span class="sourceLineNo">726</span>      int oldRack = oldServer &gt;= 0 ? serverIndexToRackIndex[oldServer] : -1;<a name="line.726"></a>
-<span class="sourceLineNo">727</span>      int newRack = serverIndexToRackIndex[newServer];<a name="line.727"></a>
-<span class="sourceLineNo">728</span>      if (newRack != oldRack) {<a name="line.728"></a>
-<span class="sourceLineNo">729</span>        regionsPerRack[newRack] = addRegion(regionsPerRack[newRack], region);<a name="line.729"></a>
-<span class="sourceLineNo">730</span>        primariesOfRegionsPerRack[newRack] =<a name="line.730"></a>
-<span class="sourceLineNo">731</span>          addRegionSorted(primariesOfRegionsPerRack[newRack], primary);<a name="line.731"></a>
-<span class="sourceLineNo">732</span>        if (oldRack &gt;= 0) {<a name="line.732"></a>
-<span class="sourceLineNo">733</span>          regionsPerRack[oldRack] = removeRegion(regionsPerRack[oldRack], region);<a name="line.733"></a>
-<span class="sourceLineNo">734</span>          primariesOfRegionsPerRack[oldRack] =<a name="line.734"></a>
-<span class="sourceLineNo">735</span>            removeRegion(primariesOfRegionsPerRack[oldRack], primary); // will still be sorted<a name="line.735"></a>
-<span class="sourceLineNo">736</span>        }<a name="line.736"></a>
-<span class="sourceLineNo">737</span>      }<a name="line.737"></a>
-<span class="sourceLineNo">738</span>    }<a name="line.738"></a>
-<span class="sourceLineNo">739</span>  }<a name="line.739"></a>
-<span class="sourceLineNo">740</span><a name="line.740"></a>
-<span class="sourceLineNo">741</span>  int[] removeRegion(int[] regions, int regionIndex) {<a name="line.741"></a>
-<span class="sourceLineNo">742</span>    // TODO: this maybe costly. Consider using linked lists<a name="line.742"></a>
-<span class="sourceLineNo">743</span>    int[] newRegions = new int[regions.length - 1];<a name="line.743"></a>
-<span class="sourceLineNo">744</span>    int i = 0;<a name="line.744"></a>
-<span class="sourceLineNo">745</span>    for (i = 0; i &lt; regions.length; i++) {<a name="line.745"></a>
-<span class="sourceLineNo">746</span>      if (regions[i] == regionIndex) {<a name="line.746"></a>
-<span class="sourceLineNo">747</span>        break;<a name="line.747"></a>
-<span class="sourceLineNo">748</span>      }<a name="line.748"></a>
-<span class="sourceLineNo">749</span>      newRegions[i] = regions[i];<a name="line.749"></a>
-<span class="sourceLineNo">750</span>    }<a name="line.750"></a>
-<span class="sourceLineNo">751</span>    System.arraycopy(regions, i + 1, newRegions, i, newRegions.length - i);<a name="line.751"></a>
+<span class="sourceLineNo">699</span>    // update for hosts<a name="line.699"></a>
+<span class="sourceLineNo">700</span>    if (multiServersPerHost) {<a name="line.700"></a>
+<span class="sourceLineNo">701</span>      updateForLocation(serverIndexToHostIndex, regionsPerHost, colocatedReplicaCountsPerHost,<a name="line.701"></a>
+<span class="sourceLineNo">702</span>        oldServer, newServer, primary, region);<a name="line.702"></a>
+<span class="sourceLineNo">703</span>    }<a name="line.703"></a>
+<span class="sourceLineNo">704</span><a name="line.704"></a>
+<span class="sourceLineNo">705</span>    // update for racks<a name="line.705"></a>
+<span class="sourceLineNo">706</span>    if (numRacks &gt; 1) {<a name="line.706"></a>
+<span class="sourceLineNo">707</span>      updateForLocation(serverIndexToRackIndex, regionsPerRack, colocatedReplicaCountsPerRack,<a name="line.707"></a>
+<span class="sourceLineNo">708</span>        oldServer, newServer, primary, region);<a name="line.708"></a>
+<span class="sourceLineNo">709</span>    }<a name="line.709"></a>
+<span class="sourceLineNo">710</span>  }<a name="line.710"></a>
+<span class="sourceLineNo">711</span>  /**<a name="line.711"></a>
+<span class="sourceLineNo">712</span>   * Common method for per host and per Location region index updates when a region is moved.<a name="line.712"></a>
+<span class="sourceLineNo">713</span>   * @param serverIndexToLocation serverIndexToHostIndex or serverIndexToLocationIndex<a name="line.713"></a>
+<span class="sourceLineNo">714</span>   * @param regionsPerLocation regionsPerHost or regionsPerLocation<a name="line.714"></a>
+<span class="sourceLineNo">715</span>   * @param colocatedReplicaCountsPerLocation colocatedReplicaCountsPerHost or<a name="line.715"></a>
+<span class="sourceLineNo">716</span>   *                                          colocatedReplicaCountsPerRack<a name="line.716"></a>
+<span class="sourceLineNo">717</span>   */<a name="line.717"></a>
+<span class="sourceLineNo">718</span>  private void updateForLocation(int[] serverIndexToLocation,<a name="line.718"></a>
+<span class="sourceLineNo">719</span>    int[][] regionsPerLocation,<a name="line.719"></a>
+<span class="sourceLineNo">720</span>    Int2IntCounterMap[] colocatedReplicaCountsPerLocation,<a name="line.720"></a>
+<span class="sourceLineNo">721</span>    int oldServer, int newServer, int primary, int region) {<a name="line.721"></a>
+<span class="sourceLineNo">722</span>    int oldLocation = oldServer &gt;= 0 ? serverIndexToLocation[oldServer] : -1;<a name="line.722"></a>
+<span class="sourceLineNo">723</span>    int newLocation = serverIndexToLocation[newServer];<a name="line.723"></a>
+<span class="sourceLineNo">724</span>    if (newLocation != oldLocation) {<a name="line.724"></a>
+<span class="sourceLineNo">725</span>      regionsPerLocation[newLocation] = addRegion(regionsPerLocation[newLocation], region);<a name="line.725"></a>
+<span class="sourceLineNo">726</span>      colocatedReplicaCountsPerLocation[newLocation].getAndIncrement(primary);<a name="line.726"></a>
+<span class="sourceLineNo">727</span>      if (oldLocation &gt;= 0) {<a name="line.727"></a>
+<span class="sourceLineNo">728</span>        regionsPerLocation[oldLocation] = removeRegion(regionsPerLocation[oldLocation], region);<a name="line.728"></a>
+<span class="sourceLineNo">729</span>        colocatedReplicaCountsPerLocation[oldLocation].getAndDecrement(primary);<a name="line.729"></a>
+<span class="sourceLineNo">730</span>      }<a name="line.730"></a>
+<span class="sourceLineNo">731</span>    }<a name="line.731"></a>
+<span class="sourceLineNo">732</span><a name="line.732"></a>
+<span class="sourceLineNo">733</span>  }<a name="line.733"></a>
+<span class="sourceLineNo">734</span>  int[] removeRegion(int[] regions, int regionIndex) {<a name="line.734"></a>
+<span class="sourceLineNo">735</span>    // TODO: this maybe costly. Consider using linked lists<a name="line.735"></a>
+<span class="sourceLineNo">736</span>    int[] newRegions = new int[regions.length - 1];<a name="line.736"></a>
+<span class="sourceLineNo">737</span>    int i = 0;<a name="line.737"></a>
+<span class="sourceLineNo">738</span>    for (i = 0; i &lt; regions.length; i++) {<a name="line.738"></a>
+<span class="sourceLineNo">739</span>      if (regions[i] == regionIndex) {<a name="line.739"></a>
+<span class="sourceLineNo">740</span>        break;<a name="line.740"></a>
+<span class="sourceLineNo">741</span>      }<a name="line.741"></a>
+<span class="sourceLineNo">742</span>      newRegions[i] = regions[i];<a name="line.742"></a>
+<span class="sourceLineNo">743</span>    }<a name="line.743"></a>
+<span class="sourceLineNo">744</span>    System.arraycopy(regions, i + 1, newRegions, i, newRegions.length - i);<a name="line.744"></a>
+<span class="sourceLineNo">745</span>    return newRegions;<a name="line.745"></a>
+<span class="sourceLineNo">746</span>  }<a name="line.746"></a>
+<span class="sourceLineNo">747</span><a name="line.747"></a>
+<span class="sourceLineNo">748</span>  int[] addRegion(int[] regions, int regionIndex) {<a name="line.748"></a>
+<span class="sourceLineNo">749</span>    int[] newRegions = new int[regions.length + 1];<a name="line.749"></a>
+<span class="sourceLineNo">750</span>    System.arraycopy(regions, 0, newRegions, 0, regions.length);<a name="line.750"></a>
+<span class="sourceLineNo">751</span>    newRegions[newRegions.length - 1] = regionIndex;<a name="line.751"></a>
 <span class="sourceLineNo">752</span>    return newRegions;<a name="line.752"></a>
 <span class="sourceLineNo">753</span>  }<a name="line.753"></a>
 <span class="sourceLineNo">754</span><a name="line.754"></a>
-<span class="sourceLineNo">755</span>  int[] addRegion(int[] regions, int regionIndex) {<a name="line.755"></a>
+<span class="sourceLineNo">755</span>  int[] addRegionSorted(int[] regions, int regionIndex) {<a name="line.755"></a>
 <span class="sourceLineNo">756</span>    int[] newRegions = new int[regions.length + 1];<a name="line.756"></a>
-<span class="sourceLineNo">757</span>    System.arraycopy(regions, 0, newRegions, 0, regions.length);<a name="line.757"></a>
-<span class="sourceLineNo">758</span>    newRegions[newRegions.length - 1] = regionIndex;<a name="line.758"></a>
-<span class="sourceLineNo">759</span>    return newRegions;<a name="line.759"></a>
-<span class="sourceLineNo">760</span>  }<a name="line.760"></a>
-<span class="sourceLineNo">761</span><a name="line.761"></a>
-<span class="sourceLineNo">762</span>  int[] addRegionSorted(int[] regions, int regionIndex) {<a name="line.762"></a>
-<span class="sourceLineNo">763</span>    int[] newRegions = new int[regions.length + 1];<a name="line.763"></a>
-<span class="sourceLineNo">764</span>    int i = 0;<a name="line.764"></a>
-<span class="sourceLineNo">765</span>    for (i = 0; i &lt; regions.length; i++) { // find the index to insert<a name="line.765"></a>
-<span class="sourceLineNo">766</span>      if (regions[i] &gt; regionIndex) {<a name="line.766"></a>
-<span class="sourceLineNo">767</span>        break;<a name="line.767"></a>
-<span class="sourceLineNo">768</span>      }<a name="line.768"></a>
-<span class="sourceLineNo">769</span>    }<a name="line.769"></a>
-<span class="sourceLineNo">770</span>    System.arraycopy(regions, 0, newRegions, 0, i); // copy first half<a name="line.770"></a>
-<span class="sourceLineNo">771</span>    System.arraycopy(regions, i, newRegions, i + 1, regions.length - i); // copy second half<a name="line.771"></a>
-<span class="sourceLineNo">772</span>    newRegions[i] = regionIndex;<a name="line.772"></a>
-<span class="sourceLineNo">773</span><a name="line.773"></a>
-<span class="sourceLineNo">774</span>    return newRegions;<a name="line.774"></a>
-<span class="sourceLineNo">775</span>  }<a name="line.775"></a>
-<span class="sourceLineNo">776</span><a name="line.776"></a>
-<span class="sourceLineNo">777</span>  int[] replaceRegion(int[] regions, int regionIndex, int newRegionIndex) {<a name="line.777"></a>
-<span class="sourceLineNo">778</span>    int i = 0;<a name="line.778"></a>
-<span class="sourceLineNo">779</span>    for (i = 0; i &lt; regions.length; i++) {<a name="line.779"></a>
-<span class="sourceLineNo">780</span>      if (regions[i] == regionIndex) {<a name="line.780"></a>
-<span class="sourceLineNo">781</span>        regions[i] = newRegionIndex;<a name="line.781"></a>
-<span class="sourceLineNo">782</span>        break;<a name="line.782"></a>
-<span class="sourceLineNo">783</span>      }<a name="line.783"></a>
-<span class="sourceLineNo">784</span>    }<a name="line.784"></a>
-<span class="sourceLineNo">785</span>    return regions;<a name="line.785"></a>
-<span class="sourceLineNo">786</span>  }<a name="line.786"></a>
-<span class="sourceLineNo">787</span><a name="line.787"></a>
-<span class="sourceLineNo">788</span>  void sortServersByRegionCount() {<a name="line.788"></a>
-<span class="sourceLineNo">789</span>    Arrays.sort(serverIndicesSortedByRegionCount, numRegionsComparator);<a name="line.789"></a>
-<span class="sourceLineNo">790</span>  }<a name="line.790"></a>
-<span class="sourceLineNo">791</span><a name="line.791"></a>
-<span class="sourceLineNo">792</span>  int getNumRegions(int server) {<a name="line.792"></a>
-<span class="sourceLineNo">793</span>    return regionsPerServer[server].length;<a name="line.793"></a>
-<span class="sourceLineNo">794</span>  }<a name="line.794"></a>
-<span class="sourceLineNo">795</span><a name="line.795"></a>
-<span class="sourceLineNo">796</span>  boolean contains(int[] arr, int val) {<a name="line.796"></a>
-<span class="sourceLineNo">797</span>    return Arrays.binarySearch(arr, val) &gt;= 0;<a name="line.797"></a>
-<span class="sourceLineNo">798</span>  }<a name="line.798"></a>
-<span class="sourceLineNo">799</span><a name="line.799"></a>
-<span class="sourceLineNo">800</span>  private Comparator&lt;Integer&gt; numRegionsComparator = Comparator.comparingInt(this::getNumRegions);<a name="line.800"></a>
-<span class="sourceLineNo">801</span><a name="line.801"></a>
-<span class="sourceLineNo">802</span>  int getLowestLocalityRegionOnServer(int serverIndex) {<a name="line.802"></a>
-<span class="sourceLineNo">803</span>    if (regionFinder != null) {<a name="line.803"></a>
-<span class="sourceLineNo">804</span>      float lowestLocality = 1.0f;<a name="line.804"></a>
-<span class="sourceLineNo">805</span>      int lowestLocalityRegionIndex = -1;<a name="line.805"></a>
-<span class="sourceLineNo">806</span>      if (regionsPerServer[serverIndex].length == 0) {<a name="line.806"></a>
-<span class="sourceLineNo">807</span>        // No regions on that region server<a name="line.807"></a>
-<span class="sourceLineNo">808</span>        return -1;<a name="line.808"></a>
-<span class="sourceLineNo">809</span>      }<a name="line.809"></a>
-<span class="sourceLineNo">810</span>      for (int j = 0; j &lt; regionsPerServer[serverIndex].length; j++) {<a name="line.810"></a>
-<span class="sourceLineNo">811</span>        int regionIndex = regionsPerServer[serverIndex][j];<a name="line.811"></a>
-<span class="sourceLineNo">812</span>        HDFSBlocksDistribution distribution =<a name="line.812"></a>
-<span class="sourceLineNo">813</span>          regionFinder.getBlockDistribution(regions[regionIndex]);<a name="line.813"></a>
-<span class="sourceLineNo">814</span>        float locality = distribution.getBlockLocalityIndex(servers[serverIndex].getHostname());<a name="line.814"></a>
-<span class="sourceLineNo">815</span>        // skip empty region<a name="line.815"></a>
-<span class="sourceLineNo">816</span>        if (distribution.getUniqueBlocksTotalWeight() == 0) {<a name="line.816"></a>
-<span class="sourceLineNo">817</span>          continue;<a name="line.817"></a>
-<span class="sourceLineNo">818</span>        }<a name="line.818"></a>
-<span class="sourceLineNo">819</span>        if (locality &lt; lowestLocality) {<a name="line.819"></a>
-<span class="sourceLineNo">820</span>          lowestLocality = locality;<a name="line.820"></a>
-<span class="sourceLineNo">821</span>          lowestLocalityRegionIndex = j;<a name="line.821"></a>
-<span class="sourceLineNo">822</span>        }<a name="line.822"></a>
-<span class="sourceLineNo">823</span>      }<a name="line.823"></a>
-<span class="sourceLineNo">824</span>      if (lowestLocalityRegionIndex == -1) {<a name="line.824"></a>
-<span class="sourceLineNo">825</span>        return -1;<a name="line.825"></a>
+<span class="sourceLineNo">757</span>    int i = 0;<a name="line.757"></a>
+<span class="sourceLineNo">758</span>    for (i = 0; i &lt; regions.length; i++) { // find the index to insert<a name="line.758"></a>
+<span class="sourceLineNo">759</span>      if (regions[i] &gt; regionIndex) {<a name="line.759"></a>
+<span class="sourceLineNo">760</span>        break;<a name="line.760"></a>
+<span class="sourceLineNo">761</span>      }<a name="line.761"></a>
+<span class="sourceLineNo">762</span>    }<a name="line.762"></a>
+<span class="sourceLineNo">763</span>    System.arraycopy(regions, 0, newRegions, 0, i); // copy first half<a name="line.763"></a>
+<span class="sourceLineNo">764</span>    System.arraycopy(regions, i, newRegions, i + 1, regions.length - i); // copy second half<a name="line.764"></a>
+<span class="sourceLineNo">765</span>    newRegions[i] = regionIndex;<a name="line.765"></a>
+<span class="sourceLineNo">766</span><a name="line.766"></a>
+<span class="sourceLineNo">767</span>    return newRegions;<a name="line.767"></a>
+<span class="sourceLineNo">768</span>  }<a name="line.768"></a>
+<span class="sourceLineNo">769</span><a name="line.769"></a>
+<span class="sourceLineNo">770</span>  int[] replaceRegion(int[] regions, int regionIndex, int newRegionIndex) {<a name="line.770"></a>
+<span class="sourceLineNo">771</span>    int i = 0;<a name="line.771"></a>
+<span class="sourceLineNo">772</span>    for (i = 0; i &lt; regions.length; i++) {<a name="line.772"></a>
+<span class="sourceLineNo">773</span>      if (regions[i] == regionIndex) {<a name="line.773"></a>
+<span class="sourceLineNo">774</span>        regions[i] = newRegionIndex;<a name="line.774"></a>
+<span class="sourceLineNo">775</span>        break;<a name="line.775"></a>
+<span class="sourceLineNo">776</span>      }<a name="line.776"></a>
+<span class="sourceLineNo">777</span>    }<a name="line.777"></a>
+<span class="sourceLineNo">778</span>    return regions;<a name="line.778"></a>
+<span class="sourceLineNo">779</span>  }<a name="line.779"></a>
+<span class="sourceLineNo">780</span><a name="line.780"></a>
+<span class="sourceLineNo">781</span>  void sortServersByRegionCount() {<a name="line.781"></a>
+<span class="sourceLineNo">782</span>    Arrays.sort(serverIndicesSortedByRegionCount, numRegionsComparator);<a name="line.782"></a>
+<span class="sourceLineNo">783</span>  }<a name="line.783"></a>
+<span class="sourceLineNo">784</span><a name="line.784"></a>
+<span class="sourceLineNo">785</span>  int getNumRegions(int server) {<a name="line.785"></a>
+<span class="sourceLineNo">786</span>    return regionsPerServer[server].length;<a name="line.786"></a>
+<span class="sourceLineNo">787</span>  }<a name="line.787"></a>
+<span class="sourceLineNo">788</span><a name="line.788"></a>
+<span class="sourceLineNo">789</span>  boolean contains(int[] arr, int val) {<a name="line.789"></a>
+<span class="sourceLineNo">790</span>    return Arrays.binarySearch(arr, val) &gt;= 0;<a name="line.790"></a>
+<span class="sourceLineNo">791</span>  }<a name="line.791"></a>
+<span class="sourceLineNo">792</span><a name="line.792"></a>
+<span class="sourceLineNo">793</span>  private Comparator&lt;Integer&gt; numRegionsComparator = Comparator.comparingInt(this::getNumRegions);<a name="line.793"></a>
+<span class="sourceLineNo">794</span><a name="line.794"></a>
+<span class="sourceLineNo">795</span>  int getLowestLocalityRegionOnServer(int serverIndex) {<a name="line.795"></a>
+<span class="sourceLineNo">796</span>    if (regionFinder != null) {<a name="line.796"></a>
+<span class="sourceLineNo">797</span>      float lowestLocality = 1.0f;<a name="line.797"></a>
+<span class="sourceLineNo">798</span>      int lowestLocalityRegionIndex = -1;<a name="line.798"></a>
+<span class="sourceLineNo">799</span>      if (regionsPerServer[serverIndex].length == 0) {<a name="line.799"></a>
+<span class="sourceLineNo">800</span>        // No regions on that region server<a name="line.800"></a>
+<span class="sourceLineNo">801</span>        return -1;<a name="line.801"></a>
+<span class="sourceLineNo">802</span>      }<a name="line.802"></a>
+<span class="sourceLineNo">803</span>      for (int j = 0; j &lt; regionsPerServer[serverIndex].length; j++) {<a name="line.803"></a>
+<span class="sourceLineNo">804</span>        int regionIndex = regionsPerServer[serverIndex][j];<a name="line.804"></a>
+<span class="sourceLineNo">805</span>        HDFSBlocksDistribution distribution =<a name="line.805"></a>
+<span class="sourceLineNo">806</span>          regionFinder.getBlockDistribution(regions[regionIndex]);<a name="line.806"></a>
+<span class="sourceLineNo">807</span>        float locality = distribution.getBlockLocalityIndex(servers[serverIndex].getHostname());<a name="line.807"></a>
+<span class="sourceLineNo">808</span>        // skip empty region<a name="line.808"></a>
+<span class="sourceLineNo">809</span>        if (distribution.getUniqueBlocksTotalWeight() == 0) {<a name="line.809"></a>
+<span class="sourceLineNo">810</span>          continue;<a name="line.810"></a>
+<span class="sourceLineNo">811</span>        }<a name="line.811"></a>
+<span class="sourceLineNo">812</span>        if (locality &lt; lowestLocality) {<a name="line.812"></a>
+<span class="sourceLineNo">813</span>          lowestLocality = locality;<a name="line.813"></a>
+<span class="sourceLineNo">814</span>          lowestLocalityRegionIndex = j;<a name="line.814"></a>
+<span class="sourceLineNo">815</span>        }<a name="line.815"></a>
+<span class="sourceLineNo">816</span>      }<a name="line.816"></a>
+<span class="sourceLineNo">817</span>      if (lowestLocalityRegionIndex == -1) {<a name="line.817"></a>
+<span class="sourceLineNo">818</span>        return -1;<a name="line.818"></a>
+<span class="sourceLineNo">819</span>      }<a name="line.819"></a>
+<span class="sourceLineNo">820</span>      if (LOG.isTraceEnabled()) {<a name="line.820"></a>
+<span class="sourceLineNo">821</span>        LOG.trace("Lowest locality region is " +<a name="line.821"></a>
+<span class="sourceLineNo">822</span>          regions[regionsPerServer[serverIndex][lowestLocalityRegionIndex]]<a name="line.822"></a>
+<span class="sourceLineNo">823</span>            .getRegionNameAsString() +<a name="line.823"></a>
+<span class="sourceLineNo">824</span>          " with locality " + lowestLocality + " and its region server contains " +<a name="line.824"></a>
+<span class="sourceLineNo">825</span>          regionsPerServer[serverIndex].length + " regions");<a name="line.825"></a>
 <span class="sourceLineNo">826</span>      }<a name="line.826"></a>
-<span class="sourceLineNo">827</span>      if (LOG.isTraceEnabled()) {<a name="line.827"></a>
-<span class="sourceLineNo">828</span>        LOG.trace("Lowest locality region is " +<a name="line.828"></a>
-<span class="sourceLineNo">829</span>          regions[regionsPerServer[serverIndex][lowestLocalityRegionIndex]]<a name="line.829"></a>
-<span class="sourceLineNo">830</span>            .getRegionNameAsString() +<a name="line.830"></a>
-<span class="sourceLineNo">831</span>          " with locality " + lowestLocality + " and its region server contains " +<a name="line.831"></a>
-<span class="sourceLineNo">832</span>          regionsPerServer[serverIndex].length + " regions");<a name="line.832"></a>
-<span class="sourceLineNo">833</span>      }<a name="line.833"></a>
-<span class="sourceLineNo">834</span>      return regionsPerServer[serverIndex][lowestLocalityRegionIndex];<a name="line.834"></a>
-<span class="sourceLineNo">835</span>    } else {<a name="line.835"></a>
-<span class="sourceLineNo">836</span>      return -1;<a name="line.836"></a>
-<span class="sourceLineNo">837</span>    }<a name="line.837"></a>
-<span class="sourceLineNo">838</span>  }<a name="line.838"></a>
-<span class="sourceLineNo">839</span><a name="line.839"></a>
-<span class="sourceLineNo">840</span>  float getLocalityOfRegion(int region, int server) {<a name="line.840"></a>
-<span class="sourceLineNo">841</span>    if (regionFinder != null) {<a name="line.841"></a>
-<span class="sourceLineNo">842</span>      HDFSBlocksDistribution distribution = regionFinder.getBlockDistribution(regions[region]);<a name="line.842"></a>
-<span class="sourceLineNo">843</span>      return distribution.getBlockLocalityIndex(servers[server].getHostname());<a name="line.843"></a>
-<span class="sourceLineNo">844</span>    } else {<a name="line.844"></a>
-<span class="sourceLineNo">845</span>      return 0f;<a name="line.845"></a>
-<span class="sourceLineNo">846</span>    }<a name="line.846"></a>
-<span class="sourceLineNo">847</span>  }<a name="line.847"></a>
-<span class="sourceLineNo">848</span><a name="line.848"></a>
-<span class="sourceLineNo">849</span>  void setNumRegions(int numRegions) {<a name="line.849"></a>
-<span class="sourceLineNo">850</span>    this.numRegions = numRegions;<a name="line.850"></a>
-<span class="sourceLineNo">851</span>  }<a name="line.851"></a>
-<span class="sourceLineNo">852</span><a name="line.852"></a>
-<span class="sourceLineNo">853</span>  void setNumMovedRegions(int numMovedRegions) {<a name="line.853"></a>
-<span class="sourceLineNo">854</span>    this.numMovedRegions = numMovedRegions;<a name="line.854"></a>
-<span class="sourceLineNo">855</span>  }<a name="line.855"></a>
-<span class="sourceLineNo">856</span><a name="line.856"></a>
-<span class="sourceLineNo">857</span>  @Override<a name="line.857"></a>
-<span class="sourceLineNo">858</span>  public String toString() {<a name="line.858"></a>
-<span class="sourceLineNo">859</span>    StringBuilder desc = new StringBuilder("Cluster={servers=[");<a name="line.859"></a>
-<span class="sourceLineNo">860</span>    for (ServerName sn : servers) {<a name="line.860"></a>
-<span class="sourceLineNo">861</span>      desc.append(sn.getAddress().toString()).append(", ");<a name="line.861"></a>
-<span class="sourceLineNo">862</span>    }<a name="line.862"></a>
-<span class="sourceLineNo">863</span>    desc.append("], serverIndicesSortedByRegionCount=")<a name="line.863"></a>
-<span class="sourceLineNo">864</span>      .append(Arrays.toString(serverIndicesSortedByRegionCount)).append(", regionsPerServer=")<a name="line.864"></a>
-<span class="sourceLineNo">865</span>      .append(Arrays.deepToString(regionsPerServer));<a name="line.865"></a>
+<span class="sourceLineNo">827</span>      return regionsPerServer[serverIndex][lowestLocalityRegionIndex];<a name="line.827"></a>
+<span class="sourceLineNo">828</span>    } else {<a name="line.828"></a>
+<span class="sourceLineNo">829</span>      return -1;<a name="line.829"></a>
+<span class="sourceLineNo">830</span>    }<a name="line.830"></a>
+<span class="sourceLineNo">831</span>  }<a name="line.831"></a>
+<span class="sourceLineNo">832</span><a name="line.832"></a>
+<span class="sourceLineNo">833</span>  float getLocalityOfRegion(int region, int server) {<a name="line.833"></a>
+<span class="sourceLineNo">834</span>    if (regionFinder != null) {<a name="line.834"></a>
+<span class="sourceLineNo">835</span>      HDFSBlocksDistribution distribution = regionFinder.getBlockDistribution(regions[region]);<a name="line.835"></a>
+<span class="sourceLineNo">836</span>      return distribution.getBlockLocalityIndex(servers[server].getHostname());<a name="line.836"></a>
+<span class="sourceLineNo">837</span>    } else {<a name="line.837"></a>
+<span class="sourceLineNo">838</span>      return 0f;<a name="line.838"></a>
+<span class="sourceLineNo">839</span>    }<a name="line.839"></a>
+<span class="sourceLineNo">840</span>  }<a name="line.840"></a>
+<span class="sourceLineNo">841</span><a name="line.841"></a>
+<span class="sourceLineNo">842</span>  void setNumRegions(int numRegions) {<a name="line.842"></a>
+<span class="sourceLineNo">843</span>    this.numRegions = numRegions;<a name="line.843"></a>
+<span class="sourceLineNo">844</span>  }<a name="line.844"></a>
+<span class="sourceLineNo">845</span><a name="line.845"></a>
+<span class="sourceLineNo">846</span>  void setNumMovedRegions(int numMovedRegions) {<a name="line.846"></a>
+<span class="sourceLineNo">847</span>    this.numMovedRegions = numMovedRegions;<a name="line.847"></a>
+<span class="sourceLineNo">848</span>  }<a name="line.848"></a>
+<span class="sourceLineNo">849</span><a name="line.849"></a>
+<span class="sourceLineNo">850</span>  @Override<a name="line.850"></a>
+<span class="sourceLineNo">851</span>  public String toString() {<a name="line.851"></a>
+<span class="sourceLineNo">852</span>    StringBuilder desc = new StringBuilder("Cluster={servers=[");<a name="line.852"></a>
+<span class="sourceLineNo">853</span>    for (ServerName sn : servers) {<a name="line.853"></a>
+<span class="sourceLineNo">854</span>      desc.append(sn.getAddress().toString()).append(", ");<a name="line.854"></a>
+<span class="sourceLineNo">855</span>    }<a name="line.855"></a>
+<span class="sourceLineNo">856</span>    desc.append("], serverIndicesSortedByRegionCount=")<a name="line.856"></a>
+<span class="sourceLineNo">857</span>      .append(Arrays.toString(serverIndicesSortedByRegionCount)).append(", regionsPerServer=")<a name="line.857"></a>
+<span class="sourceLineNo">858</span>      .append(Arrays.deepToString(regionsPerServer));<a name="line.858"></a>
+<span class="sourceLineNo">859</span><a name="line.859"></a>
+<span class="sourceLineNo">860</span>    desc.append(", regionSkewByTable=").append(Arrays.toString(regionSkewByTable))<a name="line.860"></a>
+<span class="sourceLineNo">861</span>      .append(", numRegions=").append(numRegions).append(", numServers=").append(numServers)<a name="line.861"></a>
+<span class="sourceLineNo">862</span>      .append(", numTables=").append(numTables).append(", numMovedRegions=").append(numMovedRegions)<a name="line.862"></a>
+<span class="sourceLineNo">863</span>      .append('}');<a name="line.863"></a>
+<span class="sourceLineNo">864</span>    return desc.toString();<a name="line.864"></a>
+<span class="sourceLineNo">865</span>  }<a name="line.865"></a>
 <span class="sourceLineNo">866</span><a name="line.866"></a>
-<span class="sourceLineNo">867</span>    desc.append(", regionSkewByTable=").append(Arrays.toString(regionSkewByTable))<a name="line.867"></a>
-<span class="sourceLineNo">868</span>      .append(", numRegions=").append(numRegions).append(", numServers=").append(numServers)<a name="line.868"></a>
-<span class="sourceLineNo">869</span>      .append(", numTables=").append(numTables).append(", numMovedRegions=").append(numMovedRegions)<a name="line.869"></a>
-<span class="sourceLineNo">870</span>      .append('}');<a name="line.870"></a>
-<span class="sourceLineNo">871</span>    return desc.toString();<a name="line.871"></a>
-<span class="sourceLineNo">872</span>  }<a name="line.872"></a>
-<span class="sourceLineNo">873</span><a name="line.873"></a>
-<span class="sourceLineNo">874</span>  private double getSkewChangeFor(int serverIndex, int tableIndex, int regionCountChange) {<a name="line.874"></a>
-<span class="sourceLineNo">875</span>    double curSkew = Math.abs(numRegionsPerServerPerTable[serverIndex][tableIndex] -<a name="line.875"></a>
-<span class="sourceLineNo">876</span>      meanRegionsPerTable[tableIndex]);<a name="line.876"></a>
-<span class="sourceLineNo">877</span>    double oldSkew = Math.abs(numRegionsPerServerPerTable[serverIndex][tableIndex] -<a name="line.877"></a>
-<span class="sourceLineNo">878</span>      regionCountChange - meanRegionsPerTable[tableIndex]);<a name="line.878"></a>
-<span class="sourceLineNo">879</span>    return curSkew - oldSkew;<a name="line.879"></a>
-<span class="sourceLineNo">880</span>  }<a name="line.880"></a>
-<span class="sourceLineNo">881</span>}<a name="line.881"></a>
+<span class="sourceLineNo">867</span>  private double getSkewChangeFor(int serverIndex, int tableIndex, int regionCountChange) {<a name="line.867"></a>
+<span class="sourceLineNo">868</span>    double curSkew = Math.abs(numRegionsPerServerPerTable[serverIndex][tableIndex] -<a name="line.868"></a>
+<span class="sourceLineNo">869</span>      meanRegionsPerTable[tableIndex]);<a name="line.869"></a>
+<span class="sourceLineNo">870</span>    double oldSkew = Math.abs(numRegionsPerServerPerTable[serverIndex][tableIndex] -<a name="line.870"></a>
+<span class="sourceLineNo">871</span>      regionCountChange - meanRegionsPerTable[tableIndex]);<a name="line.871"></a>
+<span class="sourceLineNo">872</span>    return curSkew - oldSkew;<a name="line.872"></a>
+<span class="sourceLineNo">873</span>  }<a name="line.873"></a>
+<span class="sourceLineNo">874</span>}<a name="line.874"></a>
 
 
 
diff --git a/devapidocs/src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html b/devapidocs/src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html
index 71d9218..d15cd10 100644
--- a/devapidocs/src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html
+++ b/devapidocs/src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html
@@ -34,859 +34,852 @@
 <span class="sourceLineNo">026</span>import java.util.HashMap;<a name="line.26"></a>
 <span class="sourceLineNo">027</span>import java.util.List;<a name="line.27"></a>
 <span class="sourceLineNo">028</span>import java.util.Map;<a name="line.28"></a>
-<span class="sourceLineNo">029</span>import org.apache.hadoop.hbase.HDFSBlocksDistribution;<a name="line.29"></a>
-<span class="sourceLineNo">030</span>import org.apache.hadoop.hbase.ServerName;<a name="line.30"></a>
-<span class="sourceLineNo">031</span>import org.apache.hadoop.hbase.client.RegionInfo;<a name="line.31"></a>
-<span class="sourceLineNo">032</span>import org.apache.hadoop.hbase.client.RegionReplicaUtil;<a name="line.32"></a>
-<span class="sourceLineNo">033</span>import org.apache.hadoop.hbase.master.RackManager;<a name="line.33"></a>
-<span class="sourceLineNo">034</span>import org.apache.hadoop.hbase.net.Address;<a name="line.34"></a>
-<span class="sourceLineNo">035</span>import org.apache.yetus.audience.InterfaceAudience;<a name="line.35"></a>
-<span class="sourceLineNo">036</span>import org.slf4j.Logger;<a name="line.36"></a>
-<span class="sourceLineNo">037</span>import org.slf4j.LoggerFactory;<a name="line.37"></a>
-<span class="sourceLineNo">038</span><a name="line.38"></a>
-<span class="sourceLineNo">039</span>/**<a name="line.39"></a>
-<span class="sourceLineNo">040</span> * An efficient array based implementation similar to ClusterState for keeping the status of the<a name="line.40"></a>
-<span class="sourceLineNo">041</span> * cluster in terms of region assignment and distribution. LoadBalancers, such as<a name="line.41"></a>
-<span class="sourceLineNo">042</span> * StochasticLoadBalancer uses this Cluster object because of hundreds of thousands of hashmap<a name="line.42"></a>
-<span class="sourceLineNo">043</span> * manipulations are very costly, which is why this class uses mostly indexes and arrays.<a name="line.43"></a>
-<span class="sourceLineNo">044</span> * &lt;p/&gt;<a name="line.44"></a>
-<span class="sourceLineNo">045</span> * BalancerClusterState tracks a list of unassigned regions, region assignments, and the server<a name="line.45"></a>
-<span class="sourceLineNo">046</span> * topology in terms of server names, hostnames and racks.<a name="line.46"></a>
-<span class="sourceLineNo">047</span> */<a name="line.47"></a>
-<span class="sourceLineNo">048</span>@InterfaceAudience.Private<a name="line.48"></a>
-<span class="sourceLineNo">049</span>class BalancerClusterState {<a name="line.49"></a>
-<span class="sourceLineNo">050</span><a name="line.50"></a>
-<span class="sourceLineNo">051</span>  private static final Logger LOG = LoggerFactory.getLogger(BalancerClusterState.class);<a name="line.51"></a>
+<span class="sourceLineNo">029</span>import org.agrona.collections.Hashing;<a name="line.29"></a>
+<span class="sourceLineNo">030</span>import org.agrona.collections.Int2IntCounterMap;<a name="line.30"></a>
+<span class="sourceLineNo">031</span>import org.apache.hadoop.hbase.HDFSBlocksDistribution;<a name="line.31"></a>
+<span class="sourceLineNo">032</span>import org.apache.hadoop.hbase.ServerName;<a name="line.32"></a>
+<span class="sourceLineNo">033</span>import org.apache.hadoop.hbase.client.RegionInfo;<a name="line.33"></a>
+<span class="sourceLineNo">034</span>import org.apache.hadoop.hbase.client.RegionReplicaUtil;<a name="line.34"></a>
+<span class="sourceLineNo">035</span>import org.apache.hadoop.hbase.master.RackManager;<a name="line.35"></a>
+<span class="sourceLineNo">036</span>import org.apache.hadoop.hbase.net.Address;<a name="line.36"></a>
+<span class="sourceLineNo">037</span>import org.apache.yetus.audience.InterfaceAudience;<a name="line.37"></a>
+<span class="sourceLineNo">038</span>import org.slf4j.Logger;<a name="line.38"></a>
+<span class="sourceLineNo">039</span>import org.slf4j.LoggerFactory;<a name="line.39"></a>
+<span class="sourceLineNo">040</span><a name="line.40"></a>
+<span class="sourceLineNo">041</span>/**<a name="line.41"></a>
+<span class="sourceLineNo">042</span> * An efficient array based implementation similar to ClusterState for keeping the status of the<a name="line.42"></a>
+<span class="sourceLineNo">043</span> * cluster in terms of region assignment and distribution. LoadBalancers, such as<a name="line.43"></a>
+<span class="sourceLineNo">044</span> * StochasticLoadBalancer uses this Cluster object because of hundreds of thousands of hashmap<a name="line.44"></a>
+<span class="sourceLineNo">045</span> * manipulations are very costly, which is why this class uses mostly indexes and arrays.<a name="line.45"></a>
+<span class="sourceLineNo">046</span> * &lt;p/&gt;<a name="line.46"></a>
+<span class="sourceLineNo">047</span> * BalancerClusterState tracks a list of unassigned regions, region assignments, and the server<a name="line.47"></a>
+<span class="sourceLineNo">048</span> * topology in terms of server names, hostnames and racks.<a name="line.48"></a>
+<span class="sourceLineNo">049</span> */<a name="line.49"></a>
+<span class="sourceLineNo">050</span>@InterfaceAudience.Private<a name="line.50"></a>
+<span class="sourceLineNo">051</span>class BalancerClusterState {<a name="line.51"></a>
 <span class="sourceLineNo">052</span><a name="line.52"></a>
-<span class="sourceLineNo">053</span>  ServerName[] servers;<a name="line.53"></a>
-<span class="sourceLineNo">054</span>  // ServerName uniquely identifies a region server. multiple RS can run on the same host<a name="line.54"></a>
-<span class="sourceLineNo">055</span>  String[] hosts;<a name="line.55"></a>
-<span class="sourceLineNo">056</span>  String[] racks;<a name="line.56"></a>
-<span class="sourceLineNo">057</span>  boolean multiServersPerHost = false; // whether or not any host has more than one server<a name="line.57"></a>
-<span class="sourceLineNo">058</span><a name="line.58"></a>
-<span class="sourceLineNo">059</span>  ArrayList&lt;String&gt; tables;<a name="line.59"></a>
-<span class="sourceLineNo">060</span>  RegionInfo[] regions;<a name="line.60"></a>
-<span class="sourceLineNo">061</span>  Deque&lt;BalancerRegionLoad&gt;[] regionLoads;<a name="line.61"></a>
-<span class="sourceLineNo">062</span>  private RegionHDFSBlockLocationFinder regionFinder;<a name="line.62"></a>
-<span class="sourceLineNo">063</span><a name="line.63"></a>
-<span class="sourceLineNo">064</span>  int[][] regionLocations; // regionIndex -&gt; list of serverIndex sorted by locality<a name="line.64"></a>
+<span class="sourceLineNo">053</span>  private static final Logger LOG = LoggerFactory.getLogger(BalancerClusterState.class);<a name="line.53"></a>
+<span class="sourceLineNo">054</span><a name="line.54"></a>
+<span class="sourceLineNo">055</span>  ServerName[] servers;<a name="line.55"></a>
+<span class="sourceLineNo">056</span>  // ServerName uniquely identifies a region server. multiple RS can run on the same host<a name="line.56"></a>
+<span class="sourceLineNo">057</span>  String[] hosts;<a name="line.57"></a>
+<span class="sourceLineNo">058</span>  String[] racks;<a name="line.58"></a>
+<span class="sourceLineNo">059</span>  boolean multiServersPerHost = false; // whether or not any host has more than one server<a name="line.59"></a>
+<span class="sourceLineNo">060</span><a name="line.60"></a>
+<span class="sourceLineNo">061</span>  ArrayList&lt;String&gt; tables;<a name="line.61"></a>
+<span class="sourceLineNo">062</span>  RegionInfo[] regions;<a name="line.62"></a>
+<span class="sourceLineNo">063</span>  Deque&lt;BalancerRegionLoad&gt;[] regionLoads;<a name="line.63"></a>
+<span class="sourceLineNo">064</span>  private RegionHDFSBlockLocationFinder regionFinder;<a name="line.64"></a>
 <span class="sourceLineNo">065</span><a name="line.65"></a>
-<span class="sourceLineNo">066</span>  int[] serverIndexToHostIndex; // serverIndex -&gt; host index<a name="line.66"></a>
-<span class="sourceLineNo">067</span>  int[] serverIndexToRackIndex; // serverIndex -&gt; rack index<a name="line.67"></a>
-<span class="sourceLineNo">068</span><a name="line.68"></a>
-<span class="sourceLineNo">069</span>  int[][] regionsPerServer; // serverIndex -&gt; region list<a name="line.69"></a>
-<span class="sourceLineNo">070</span>  int[] serverIndexToRegionsOffset; // serverIndex -&gt; offset of region list<a name="line.70"></a>
-<span class="sourceLineNo">071</span>  int[][] regionsPerHost; // hostIndex -&gt; list of regions<a name="line.71"></a>
-<span class="sourceLineNo">072</span>  int[][] regionsPerRack; // rackIndex -&gt; region list<a name="line.72"></a>
-<span class="sourceLineNo">073</span>  int[][] primariesOfRegionsPerServer; // serverIndex -&gt; sorted list of regions by primary region<a name="line.73"></a>
-<span class="sourceLineNo">074</span>                                       // index<a name="line.74"></a>
-<span class="sourceLineNo">075</span>  int[][] primariesOfRegionsPerHost; // hostIndex -&gt; sorted list of regions by primary region index<a name="line.75"></a>
-<span class="sourceLineNo">076</span>  int[][] primariesOfRegionsPerRack; // rackIndex -&gt; sorted list of regions by primary region index<a name="line.76"></a>
-<span class="sourceLineNo">077</span><a name="line.77"></a>
-<span class="sourceLineNo">078</span>  int[][] serversPerHost; // hostIndex -&gt; list of server indexes<a name="line.78"></a>
-<span class="sourceLineNo">079</span>  int[][] serversPerRack; // rackIndex -&gt; list of server indexes<a name="line.79"></a>
-<span class="sourceLineNo">080</span>  int[] regionIndexToServerIndex; // regionIndex -&gt; serverIndex<a name="line.80"></a>
-<span class="sourceLineNo">081</span>  int[] initialRegionIndexToServerIndex; // regionIndex -&gt; serverIndex (initial cluster state)<a name="line.81"></a>
-<span class="sourceLineNo">082</span>  int[] regionIndexToTableIndex; // regionIndex -&gt; tableIndex<a name="line.82"></a>
-<span class="sourceLineNo">083</span>  int[][] numRegionsPerServerPerTable; // serverIndex -&gt; tableIndex -&gt; # regions<a name="line.83"></a>
-<span class="sourceLineNo">084</span>  int[] numRegionsPerTable; // tableIndex -&gt; region count<a name="line.84"></a>
-<span class="sourceLineNo">085</span>  double[] meanRegionsPerTable; // mean region count per table<a name="line.85"></a>
-<span class="sourceLineNo">086</span>  double[] regionSkewByTable;       // skew on RS per by table<a name="line.86"></a>
-<span class="sourceLineNo">087</span>  double[] minRegionSkewByTable;       // min skew on RS per by table<a name="line.87"></a>
-<span class="sourceLineNo">088</span>  double[] maxRegionSkewByTable;       // max skew on RS per by table<a name="line.88"></a>
-<span class="sourceLineNo">089</span>  int[] regionIndexToPrimaryIndex; // regionIndex -&gt; regionIndex of the primary<a name="line.89"></a>
-<span class="sourceLineNo">090</span>  boolean hasRegionReplicas = false; // whether there is regions with replicas<a name="line.90"></a>
-<span class="sourceLineNo">091</span><a name="line.91"></a>
-<span class="sourceLineNo">092</span>  Integer[] serverIndicesSortedByRegionCount;<a name="line.92"></a>
-<span class="sourceLineNo">093</span>  Integer[] serverIndicesSortedByLocality;<a name="line.93"></a>
-<span class="sourceLineNo">094</span><a name="line.94"></a>
-<span class="sourceLineNo">095</span>  Map&lt;Address, Integer&gt; serversToIndex;<a name="line.95"></a>
-<span class="sourceLineNo">096</span>  Map&lt;String, Integer&gt; hostsToIndex;<a name="line.96"></a>
-<span class="sourceLineNo">097</span>  Map&lt;String, Integer&gt; racksToIndex;<a name="line.97"></a>
-<span class="sourceLineNo">098</span>  Map&lt;String, Integer&gt; tablesToIndex;<a name="line.98"></a>
-<span class="sourceLineNo">099</span>  Map&lt;RegionInfo, Integer&gt; regionsToIndex;<a name="line.99"></a>
-<span class="sourceLineNo">100</span>  float[] localityPerServer;<a name="line.100"></a>
-<span class="sourceLineNo">101</span><a name="line.101"></a>
-<span class="sourceLineNo">102</span>  int numServers;<a name="line.102"></a>
-<span class="sourceLineNo">103</span>  int numHosts;<a name="line.103"></a>
-<span class="sourceLineNo">104</span>  int numRacks;<a name="line.104"></a>
-<span class="sourceLineNo">105</span>  int numTables;<a name="line.105"></a>
-<span class="sourceLineNo">106</span>  int numRegions;<a name="line.106"></a>
-<span class="sourceLineNo">107</span><a name="line.107"></a>
-<span class="sourceLineNo">108</span>  int numMovedRegions = 0; // num moved regions from the initial configuration<a name="line.108"></a>
-<span class="sourceLineNo">109</span>  Map&lt;ServerName, List&lt;RegionInfo&gt;&gt; clusterState;<a name="line.109"></a>
-<span class="sourceLineNo">110</span><a name="line.110"></a>
-<span class="sourceLineNo">111</span>  private final RackManager rackManager;<a name="line.111"></a>
-<span class="sourceLineNo">112</span>  // Maps region -&gt; rackIndex -&gt; locality of region on rack<a name="line.112"></a>
-<span class="sourceLineNo">113</span>  private float[][] rackLocalities;<a name="line.113"></a>
-<span class="sourceLineNo">114</span>  // Maps localityType -&gt; region -&gt; [server|rack]Index with highest locality<a name="line.114"></a>
-<span class="sourceLineNo">115</span>  private int[][] regionsToMostLocalEntities;<a name="line.115"></a>
-<span class="sourceLineNo">116</span><a name="line.116"></a>
-<span class="sourceLineNo">117</span>  static class DefaultRackManager extends RackManager {<a name="line.117"></a>
-<span class="sourceLineNo">118</span>    @Override<a name="line.118"></a>
-<span class="sourceLineNo">119</span>    public String getRack(ServerName server) {<a name="line.119"></a>
-<span class="sourceLineNo">120</span>      return UNKNOWN_RACK;<a name="line.120"></a>
-<span class="sourceLineNo">121</span>    }<a name="line.121"></a>
-<span class="sourceLineNo">122</span>  }<a name="line.122"></a>
-<span class="sourceLineNo">123</span><a name="line.123"></a>
-<span class="sourceLineNo">124</span>  BalancerClusterState(Map&lt;ServerName, List&lt;RegionInfo&gt;&gt; clusterState,<a name="line.124"></a>
-<span class="sourceLineNo">125</span>    Map&lt;String, Deque&lt;BalancerRegionLoad&gt;&gt; loads, RegionHDFSBlockLocationFinder regionFinder,<a name="line.125"></a>
-<span class="sourceLineNo">126</span>    RackManager rackManager) {<a name="line.126"></a>
-<span class="sourceLineNo">127</span>    this(null, clusterState, loads, regionFinder, rackManager);<a name="line.127"></a>
-<span class="sourceLineNo">128</span>  }<a name="line.128"></a>
-<span class="sourceLineNo">129</span><a name="line.129"></a>
-<span class="sourceLineNo">130</span>  @SuppressWarnings("unchecked")<a name="line.130"></a>
-<span class="sourceLineNo">131</span>  BalancerClusterState(Collection&lt;RegionInfo&gt; unassignedRegions,<a name="line.131"></a>
-<span class="sourceLineNo">132</span>    Map&lt;ServerName, List&lt;RegionInfo&gt;&gt; clusterState, Map&lt;String, Deque&lt;BalancerRegionLoad&gt;&gt; loads,<a name="line.132"></a>
-<span class="sourceLineNo">133</span>    RegionHDFSBlockLocationFinder regionFinder, RackManager rackManager) {<a name="line.133"></a>
-<span class="sourceLineNo">134</span>    if (unassignedRegions == null) {<a name="line.134"></a>
-<span class="sourceLineNo">135</span>      unassignedRegions = Collections.emptyList();<a name="line.135"></a>
-<span class="sourceLineNo">136</span>    }<a name="line.136"></a>
-<span class="sourceLineNo">137</span><a name="line.137"></a>
-<span class="sourceLineNo">138</span>    serversToIndex = new HashMap&lt;&gt;();<a name="line.138"></a>
-<span class="sourceLineNo">139</span>    hostsToIndex = new HashMap&lt;&gt;();<a name="line.139"></a>
-<span class="sourceLineNo">140</span>    racksToIndex = new HashMap&lt;&gt;();<a name="line.140"></a>
-<span class="sourceLineNo">141</span>    tablesToIndex = new HashMap&lt;&gt;();<a name="line.141"></a>
-<span class="sourceLineNo">142</span><a name="line.142"></a>
-<span class="sourceLineNo">143</span>    // TODO: We should get the list of tables from master<a name="line.143"></a>
-<span class="sourceLineNo">144</span>    tables = new ArrayList&lt;&gt;();<a name="line.144"></a>
-<span class="sourceLineNo">145</span>    this.rackManager = rackManager != null ? rackManager : new DefaultRackManager();<a name="line.145"></a>
+<span class="sourceLineNo">066</span>  int[][] regionLocations; // regionIndex -&gt; list of serverIndex sorted by locality<a name="line.66"></a>
+<span class="sourceLineNo">067</span><a name="line.67"></a>
+<span class="sourceLineNo">068</span>  int[] serverIndexToHostIndex; // serverIndex -&gt; host index<a name="line.68"></a>
+<span class="sourceLineNo">069</span>  int[] serverIndexToRackIndex; // serverIndex -&gt; rack index<a name="line.69"></a>
+<span class="sourceLineNo">070</span><a name="line.70"></a>
+<span class="sourceLineNo">071</span>  int[][] regionsPerServer; // serverIndex -&gt; region list<a name="line.71"></a>
+<span class="sourceLineNo">072</span>  int[] serverIndexToRegionsOffset; // serverIndex -&gt; offset of region list<a name="line.72"></a>
+<span class="sourceLineNo">073</span>  int[][] regionsPerHost; // hostIndex -&gt; list of regions<a name="line.73"></a>
+<span class="sourceLineNo">074</span>  int[][] regionsPerRack; // rackIndex -&gt; region list<a name="line.74"></a>
+<span class="sourceLineNo">075</span>  Int2IntCounterMap[] colocatedReplicaCountsPerServer; // serverIndex -&gt; counts of colocated<a name="line.75"></a>
+<span class="sourceLineNo">076</span>                                       // replicas by primary region index<a name="line.76"></a>
+<span class="sourceLineNo">077</span>  Int2IntCounterMap[] colocatedReplicaCountsPerHost; // hostIndex -&gt; counts of colocated replicas by<a name="line.77"></a>
+<span class="sourceLineNo">078</span>                                      // primary region index<a name="line.78"></a>
+<span class="sourceLineNo">079</span>  Int2IntCounterMap[] colocatedReplicaCountsPerRack; // rackIndex -&gt; counts of colocated replicas by<a name="line.79"></a>
+<span class="sourceLineNo">080</span>                                      // primary region index<a name="line.80"></a>
+<span class="sourceLineNo">081</span><a name="line.81"></a>
+<span class="sourceLineNo">082</span>  int[][] serversPerHost; // hostIndex -&gt; list of server indexes<a name="line.82"></a>
+<span class="sourceLineNo">083</span>  int[][] serversPerRack; // rackIndex -&gt; list of server indexes<a name="line.83"></a>
+<span class="sourceLineNo">084</span>  int[] regionIndexToServerIndex; // regionIndex -&gt; serverIndex<a name="line.84"></a>
+<span class="sourceLineNo">085</span>  int[] initialRegionIndexToServerIndex; // regionIndex -&gt; serverIndex (initial cluster state)<a name="line.85"></a>
+<span class="sourceLineNo">086</span>  int[] regionIndexToTableIndex; // regionIndex -&gt; tableIndex<a name="line.86"></a>
+<span class="sourceLineNo">087</span>  int[][] numRegionsPerServerPerTable; // serverIndex -&gt; tableIndex -&gt; # regions<a name="line.87"></a>
+<span class="sourceLineNo">088</span>  int[] numRegionsPerTable; // tableIndex -&gt; region count<a name="line.88"></a>
+<span class="sourceLineNo">089</span>  double[] meanRegionsPerTable; // mean region count per table<a name="line.89"></a>
+<span class="sourceLineNo">090</span>  double[] regionSkewByTable;       // skew on RS per by table<a name="line.90"></a>
+<span class="sourceLineNo">091</span>  double[] minRegionSkewByTable;       // min skew on RS per by table<a name="line.91"></a>
+<span class="sourceLineNo">092</span>  double[] maxRegionSkewByTable;       // max skew on RS per by table<a name="line.92"></a>
+<span class="sourceLineNo">093</span>  int[] regionIndexToPrimaryIndex; // regionIndex -&gt; regionIndex of the primary<a name="line.93"></a>
+<span class="sourceLineNo">094</span>  boolean hasRegionReplicas = false; // whether there is regions with replicas<a name="line.94"></a>
+<span class="sourceLineNo">095</span><a name="line.95"></a>
+<span class="sourceLineNo">096</span>  Integer[] serverIndicesSortedByRegionCount;<a name="line.96"></a>
+<span class="sourceLineNo">097</span>  Integer[] serverIndicesSortedByLocality;<a name="line.97"></a>
+<span class="sourceLineNo">098</span><a name="line.98"></a>
+<span class="sourceLineNo">099</span>  Map&lt;Address, Integer&gt; serversToIndex;<a name="line.99"></a>
+<span class="sourceLineNo">100</span>  Map&lt;String, Integer&gt; hostsToIndex;<a name="line.100"></a>
+<span class="sourceLineNo">101</span>  Map&lt;String, Integer&gt; racksToIndex;<a name="line.101"></a>
+<span class="sourceLineNo">102</span>  Map&lt;String, Integer&gt; tablesToIndex;<a name="line.102"></a>
+<span class="sourceLineNo">103</span>  Map&lt;RegionInfo, Integer&gt; regionsToIndex;<a name="line.103"></a>
+<span class="sourceLineNo">104</span>  float[] localityPerServer;<a name="line.104"></a>
+<span class="sourceLineNo">105</span><a name="line.105"></a>
+<span class="sourceLineNo">106</span>  int numServers;<a name="line.106"></a>
+<span class="sourceLineNo">107</span>  int numHosts;<a name="line.107"></a>
+<span class="sourceLineNo">108</span>  int numRacks;<a name="line.108"></a>
+<span class="sourceLineNo">109</span>  int numTables;<a name="line.109"></a>
+<span class="sourceLineNo">110</span>  int numRegions;<a name="line.110"></a>
+<span class="sourceLineNo">111</span><a name="line.111"></a>
+<span class="sourceLineNo">112</span>  int numMovedRegions = 0; // num moved regions from the initial configuration<a name="line.112"></a>
+<span class="sourceLineNo">113</span>  Map&lt;ServerName, List&lt;RegionInfo&gt;&gt; clusterState;<a name="line.113"></a>
+<span class="sourceLineNo">114</span><a name="line.114"></a>
+<span class="sourceLineNo">115</span>  private final RackManager rackManager;<a name="line.115"></a>
+<span class="sourceLineNo">116</span>  // Maps region -&gt; rackIndex -&gt; locality of region on rack<a name="line.116"></a>
+<span class="sourceLineNo">117</span>  private float[][] rackLocalities;<a name="line.117"></a>
+<span class="sourceLineNo">118</span>  // Maps localityType -&gt; region -&gt; [server|rack]Index with highest locality<a name="line.118"></a>
+<span class="sourceLineNo">119</span>  private int[][] regionsToMostLocalEntities;<a name="line.119"></a>
+<span class="sourceLineNo">120</span><a name="line.120"></a>
+<span class="sourceLineNo">121</span>  static class DefaultRackManager extends RackManager {<a name="line.121"></a>
+<span class="sourceLineNo">122</span>    @Override<a name="line.122"></a>
+<span class="sourceLineNo">123</span>    public String getRack(ServerName server) {<a name="line.123"></a>
+<span class="sourceLineNo">124</span>      return UNKNOWN_RACK;<a name="line.124"></a>
+<span class="sourceLineNo">125</span>    }<a name="line.125"></a>
+<span class="sourceLineNo">126</span>  }<a name="line.126"></a>
+<span class="sourceLineNo">127</span><a name="line.127"></a>
+<span class="sourceLineNo">128</span>  BalancerClusterState(Map&lt;ServerName, List&lt;RegionInfo&gt;&gt; clusterState,<a name="line.128"></a>
+<span class="sourceLineNo">129</span>    Map&lt;String, Deque&lt;BalancerRegionLoad&gt;&gt; loads, RegionHDFSBlockLocationFinder regionFinder,<a name="line.129"></a>
+<span class="sourceLineNo">130</span>    RackManager rackManager) {<a name="line.130"></a>
+<span class="sourceLineNo">131</span>    this(null, clusterState, loads, regionFinder, rackManager);<a name="line.131"></a>
+<span class="sourceLineNo">132</span>  }<a name="line.132"></a>
+<span class="sourceLineNo">133</span><a name="line.133"></a>
+<span class="sourceLineNo">134</span>  @SuppressWarnings("unchecked")<a name="line.134"></a>
+<span class="sourceLineNo">135</span>  BalancerClusterState(Collection&lt;RegionInfo&gt; unassignedRegions,<a name="line.135"></a>
+<span class="sourceLineNo">136</span>    Map&lt;ServerName, List&lt;RegionInfo&gt;&gt; clusterState, Map&lt;String, Deque&lt;BalancerRegionLoad&gt;&gt; loads,<a name="line.136"></a>
+<span class="sourceLineNo">137</span>    RegionHDFSBlockLocationFinder regionFinder, RackManager rackManager) {<a name="line.137"></a>
+<span class="sourceLineNo">138</span>    if (unassignedRegions == null) {<a name="line.138"></a>
+<span class="sourceLineNo">139</span>      unassignedRegions = Collections.emptyList();<a name="line.139"></a>
+<span class="sourceLineNo">140</span>    }<a name="line.140"></a>
+<span class="sourceLineNo">141</span><a name="line.141"></a>
+<span class="sourceLineNo">142</span>    serversToIndex = new HashMap&lt;&gt;();<a name="line.142"></a>
+<span class="sourceLineNo">143</span>    hostsToIndex = new HashMap&lt;&gt;();<a name="line.143"></a>
+<span class="sourceLineNo">144</span>    racksToIndex = new HashMap&lt;&gt;();<a name="line.144"></a>
+<span class="sourceLineNo">145</span>    tablesToIndex = new HashMap&lt;&gt;();<a name="line.145"></a>
 <span class="sourceLineNo">146</span><a name="line.146"></a>
-<span class="sourceLineNo">147</span>    numRegions = 0;<a name="line.147"></a>
-<span class="sourceLineNo">148</span><a name="line.148"></a>
-<span class="sourceLineNo">149</span>    List&lt;List&lt;Integer&gt;&gt; serversPerHostList = new ArrayList&lt;&gt;();<a name="line.149"></a>
-<span class="sourceLineNo">150</span>    List&lt;List&lt;Integer&gt;&gt; serversPerRackList = new ArrayList&lt;&gt;();<a name="line.150"></a>
-<span class="sourceLineNo">151</span>    this.clusterState = clusterState;<a name="line.151"></a>
-<span class="sourceLineNo">152</span>    this.regionFinder = regionFinder;<a name="line.152"></a>
-<span class="sourceLineNo">153</span><a name="line.153"></a>
-<span class="sourceLineNo">154</span>    // Use servername and port as there can be dead servers in this list. We want everything with<a name="line.154"></a>
-<span class="sourceLineNo">155</span>    // a matching hostname and port to have the same index.<a name="line.155"></a>
-<span class="sourceLineNo">156</span>    for (ServerName sn : clusterState.keySet()) {<a name="line.156"></a>
-<span class="sourceLineNo">157</span>      if (sn == null) {<a name="line.157"></a>
-<span class="sourceLineNo">158</span>        LOG.warn("TODO: Enable TRACE on BaseLoadBalancer. Empty servername); " +<a name="line.158"></a>
-<span class="sourceLineNo">159</span>          "skipping; unassigned regions?");<a name="line.159"></a>
-<span class="sourceLineNo">160</span>        if (LOG.isTraceEnabled()) {<a name="line.160"></a>
-<span class="sourceLineNo">161</span>          LOG.trace("EMPTY SERVERNAME " + clusterState.toString());<a name="line.161"></a>
-<span class="sourceLineNo">162</span>        }<a name="line.162"></a>
-<span class="sourceLineNo">163</span>        continue;<a name="line.163"></a>
-<span class="sourceLineNo">164</span>      }<a name="line.164"></a>
-<span class="sourceLineNo">165</span>      if (serversToIndex.get(sn.getAddress()) == null) {<a name="line.165"></a>
-<span class="sourceLineNo">166</span>        serversToIndex.put(sn.getAddress(), numServers++);<a name="line.166"></a>
-<span class="sourceLineNo">167</span>      }<a name="line.167"></a>
-<span class="sourceLineNo">168</span>      if (!hostsToIndex.containsKey(sn.getHostname())) {<a name="line.168"></a>
-<span class="sourceLineNo">169</span>        hostsToIndex.put(sn.getHostname(), numHosts++);<a name="line.169"></a>
-<span class="sourceLineNo">170</span>        serversPerHostList.add(new ArrayList&lt;&gt;(1));<a name="line.170"></a>
+<span class="sourceLineNo">147</span>    // TODO: We should get the list of tables from master<a name="line.147"></a>
+<span class="sourceLineNo">148</span>    tables = new ArrayList&lt;&gt;();<a name="line.148"></a>
+<span class="sourceLineNo">149</span>    this.rackManager = rackManager != null ? rackManager : new DefaultRackManager();<a name="line.149"></a>
+<span class="sourceLineNo">150</span><a name="line.150"></a>
+<span class="sourceLineNo">151</span>    numRegions = 0;<a name="line.151"></a>
+<span class="sourceLineNo">152</span><a name="line.152"></a>
+<span class="sourceLineNo">153</span>    List&lt;List&lt;Integer&gt;&gt; serversPerHostList = new ArrayList&lt;&gt;();<a name="line.153"></a>
+<span class="sourceLineNo">154</span>    List&lt;List&lt;Integer&gt;&gt; serversPerRackList = new ArrayList&lt;&gt;();<a name="line.154"></a>
+<span class="sourceLineNo">155</span>    this.clusterState = clusterState;<a name="line.155"></a>
+<span class="sourceLineNo">156</span>    this.regionFinder = regionFinder;<a name="line.156"></a>
+<span class="sourceLineNo">157</span><a name="line.157"></a>
+<span class="sourceLineNo">158</span>    // Use servername and port as there can be dead servers in this list. We want everything with<a name="line.158"></a>
+<span class="sourceLineNo">159</span>    // a matching hostname and port to have the same index.<a name="line.159"></a>
+<span class="sourceLineNo">160</span>    for (ServerName sn : clusterState.keySet()) {<a name="line.160"></a>
+<span class="sourceLineNo">161</span>      if (sn == null) {<a name="line.161"></a>
+<span class="sourceLineNo">162</span>        LOG.warn("TODO: Enable TRACE on BaseLoadBalancer. Empty servername); " +<a name="line.162"></a>
+<span class="sourceLineNo">163</span>          "skipping; unassigned regions?");<a name="line.163"></a>
+<span class="sourceLineNo">164</span>        if (LOG.isTraceEnabled()) {<a name="line.164"></a>
+<span class="sourceLineNo">165</span>          LOG.trace("EMPTY SERVERNAME " + clusterState.toString());<a name="line.165"></a>
+<span class="sourceLineNo">166</span>        }<a name="line.166"></a>
+<span class="sourceLineNo">167</span>        continue;<a name="line.167"></a>
+<span class="sourceLineNo">168</span>      }<a name="line.168"></a>
+<span class="sourceLineNo">169</span>      if (serversToIndex.get(sn.getAddress()) == null) {<a name="line.169"></a>
+<span class="sourceLineNo">170</span>        serversToIndex.put(sn.getAddress(), numServers++);<a name="line.170"></a>
 <span class="sourceLineNo">171</span>      }<a name="line.171"></a>
-<span class="sourceLineNo">172</span><a name="line.172"></a>
-<span class="sourceLineNo">173</span>      int serverIndex = serversToIndex.get(sn.getAddress());<a name="line.173"></a>
-<span class="sourceLineNo">174</span>      int hostIndex = hostsToIndex.get(sn.getHostname());<a name="line.174"></a>
-<span class="sourceLineNo">175</span>      serversPerHostList.get(hostIndex).add(serverIndex);<a name="line.175"></a>
+<span class="sourceLineNo">172</span>      if (!hostsToIndex.containsKey(sn.getHostname())) {<a name="line.172"></a>
+<span class="sourceLineNo">173</span>        hostsToIndex.put(sn.getHostname(), numHosts++);<a name="line.173"></a>
+<span class="sourceLineNo">174</span>        serversPerHostList.add(new ArrayList&lt;&gt;(1));<a name="line.174"></a>
+<span class="sourceLineNo">175</span>      }<a name="line.175"></a>
 <span class="sourceLineNo">176</span><a name="line.176"></a>
-<span class="sourceLineNo">177</span>      String rack = this.rackManager.getRack(sn);<a name="line.177"></a>
-<span class="sourceLineNo">178</span>      if (!racksToIndex.containsKey(rack)) {<a name="line.178"></a>
-<span class="sourceLineNo">179</span>        racksToIndex.put(rack, numRacks++);<a name="line.179"></a>
-<span class="sourceLineNo">180</span>        serversPerRackList.add(new ArrayList&lt;&gt;());<a name="line.180"></a>
-<span class="sourceLineNo">181</span>      }<a name="line.181"></a>
-<span class="sourceLineNo">182</span>      int rackIndex = racksToIndex.get(rack);<a name="line.182"></a>
-<span class="sourceLineNo">183</span>      serversPerRackList.get(rackIndex).add(serverIndex);<a name="line.183"></a>
-<span class="sourceLineNo">184</span>    }<a name="line.184"></a>
-<span class="sourceLineNo">185</span><a name="line.185"></a>
-<span class="sourceLineNo">186</span>    // Count how many regions there are.<a name="line.186"></a>
-<span class="sourceLineNo">187</span>    for (Map.Entry&lt;ServerName, List&lt;RegionInfo&gt;&gt; entry : clusterState.entrySet()) {<a name="line.187"></a>
-<span class="sourceLineNo">188</span>      numRegions += entry.getValue().size();<a name="line.188"></a>
-<span class="sourceLineNo">189</span>    }<a name="line.189"></a>
-<span class="sourceLineNo">190</span>    numRegions += unassignedRegions.size();<a name="line.190"></a>
-<span class="sourceLineNo">191</span><a name="line.191"></a>
-<span class="sourceLineNo">192</span>    regionsToIndex = new HashMap&lt;&gt;(numRegions);<a name="line.192"></a>
-<span class="sourceLineNo">193</span>    servers = new ServerName[numServers];<a name="line.193"></a>
-<span class="sourceLineNo">194</span>    serversPerHost = new int[numHosts][];<a name="line.194"></a>
-<span class="sourceLineNo">195</span>    serversPerRack = new int[numRacks][];<a name="line.195"></a>
-<span class="sourceLineNo">196</span>    regions = new RegionInfo[numRegions];<a name="line.196"></a>
-<span class="sourceLineNo">197</span>    regionIndexToServerIndex = new int[numRegions];<a name="line.197"></a>
-<span class="sourceLineNo">198</span>    initialRegionIndexToServerIndex = new int[numRegions];<a name="line.198"></a>
-<span class="sourceLineNo">199</span>    regionIndexToTableIndex = new int[numRegions];<a name="line.199"></a>
-<span class="sourceLineNo">200</span>    regionIndexToPrimaryIndex = new int[numRegions];<a name="line.200"></a>
-<span class="sourceLineNo">201</span>    regionLoads = new Deque[numRegions];<a name="line.201"></a>
-<span class="sourceLineNo">202</span><a name="line.202"></a>
-<span class="sourceLineNo">203</span>    regionLocations = new int[numRegions][];<a name="line.203"></a>
-<span class="sourceLineNo">204</span>    serverIndicesSortedByRegionCount = new Integer[numServers];<a name="line.204"></a>
-<span class="sourceLineNo">205</span>    serverIndicesSortedByLocality = new Integer[numServers];<a name="line.205"></a>
-<span class="sourceLineNo">206</span>    localityPerServer = new float[numServers];<a name="line.206"></a>
-<span class="sourceLineNo">207</span><a name="line.207"></a>
-<span class="sourceLineNo">208</span>    serverIndexToHostIndex = new int[numServers];<a name="line.208"></a>
-<span class="sourceLineNo">209</span>    serverIndexToRackIndex = new int[numServers];<a name="line.209"></a>
-<span class="sourceLineNo">210</span>    regionsPerServer = new int[numServers][];<a name="line.210"></a>
-<span class="sourceLineNo">211</span>    serverIndexToRegionsOffset = new int[numServers];<a name="line.211"></a>
-<span class="sourceLineNo">212</span>    regionsPerHost = new int[numHosts][];<a name="line.212"></a>
-<span class="sourceLineNo">213</span>    regionsPerRack = new int[numRacks][];<a name="line.213"></a>
-<span class="sourceLineNo">214</span>    primariesOfRegionsPerServer = new int[numServers][];<a name="line.214"></a>
-<span class="sourceLineNo">215</span>    primariesOfRegionsPerHost = new int[numHosts][];<a name="line.215"></a>
-<span class="sourceLineNo">216</span>    primariesOfRegionsPerRack = new int[numRacks][];<a name="line.216"></a>
-<span class="sourceLineNo">217</span><a name="line.217"></a>
-<span class="sourceLineNo">218</span>    int tableIndex = 0, regionIndex = 0, regionPerServerIndex = 0;<a name="line.218"></a>
-<span class="sourceLineNo">219</span><a name="line.219"></a>
-<span class="sourceLineNo">220</span>    for (Map.Entry&lt;ServerName, List&lt;RegionInfo&gt;&gt; entry : clusterState.entrySet()) {<a name="line.220"></a>
-<span class="sourceLineNo">221</span>      if (entry.getKey() == null) {<a name="line.221"></a>
-<span class="sourceLineNo">222</span>        LOG.warn("SERVERNAME IS NULL, skipping " + entry.getValue());<a name="line.222"></a>
-<span class="sourceLineNo">223</span>        continue;<a name="line.223"></a>
-<span class="sourceLineNo">224</span>      }<a name="line.224"></a>
-<span class="sourceLineNo">225</span>      int serverIndex = serversToIndex.get(entry.getKey().getAddress());<a name="line.225"></a>
-<span class="sourceLineNo">226</span><a name="line.226"></a>
-<span class="sourceLineNo">227</span>      // keep the servername if this is the first server name for this hostname<a name="line.227"></a>
-<span class="sourceLineNo">228</span>      // or this servername has the newest startcode.<a name="line.228"></a>
-<span class="sourceLineNo">229</span>      if (servers[serverIndex] == null ||<a name="line.229"></a>
-<span class="sourceLineNo">230</span>        servers[serverIndex].getStartcode() &lt; entry.getKey().getStartcode()) {<a name="line.230"></a>
-<span class="sourceLineNo">231</span>        servers[serverIndex] = entry.getKey();<a name="line.231"></a>
-<span class="sourceLineNo">232</span>      }<a name="line.232"></a>
-<span class="sourceLineNo">233</span><a name="line.233"></a>
-<span class="sourceLineNo">234</span>      if (regionsPerServer[serverIndex] != null) {<a name="line.234"></a>
-<span class="sourceLineNo">235</span>        // there is another server with the same hostAndPort in ClusterState.<a name="line.235"></a>
-<span class="sourceLineNo">236</span>        // allocate the array for the total size<a name="line.236"></a>
-<span class="sourceLineNo">237</span>        regionsPerServer[serverIndex] =<a name="line.237"></a>
-<span class="sourceLineNo">238</span>          new int[entry.getValue().size() + regionsPerServer[serverIndex].length];<a name="line.238"></a>
-<span class="sourceLineNo">239</span>      } else {<a name="line.239"></a>
-<span class="sourceLineNo">240</span>        regionsPerServer[serverIndex] = new int[entry.getValue().size()];<a name="line.240"></a>
-<span class="sourceLineNo">241</span>      }<a name="line.241"></a>
-<span class="sourceLineNo">242</span>      primariesOfRegionsPerServer[serverIndex] = new int[regionsPerServer[serverIndex].length];<a name="line.242"></a>
-<span class="sourceLineNo">243</span>      serverIndicesSortedByRegionCount[serverIndex] = serverIndex;<a name="line.243"></a>
-<span class="sourceLineNo">244</span>      serverIndicesSortedByLocality[serverIndex] = serverIndex;<a name="line.244"></a>
-<span class="sourceLineNo">245</span>    }<a name="line.245"></a>
-<span class="sourceLineNo">246</span><a name="line.246"></a>
-<span class="sourceLineNo">247</span>    hosts = new String[numHosts];<a name="line.247"></a>
-<span class="sourceLineNo">248</span>    for (Map.Entry&lt;String, Integer&gt; entry : hostsToIndex.entrySet()) {<a name="line.248"></a>
-<span class="sourceLineNo">249</span>      hosts[entry.getValue()] = entry.getKey();<a name="line.249"></a>
+<span class="sourceLineNo">177</span>      int serverIndex = serversToIndex.get(sn.getAddress());<a name="line.177"></a>
+<span class="sourceLineNo">178</span>      int hostIndex = hostsToIndex.get(sn.getHostname());<a name="line.178"></a>
+<span class="sourceLineNo">179</span>      serversPerHostList.get(hostIndex).add(serverIndex);<a name="line.179"></a>
+<span class="sourceLineNo">180</span><a name="line.180"></a>
+<span class="sourceLineNo">181</span>      String rack = this.rackManager.getRack(sn);<a name="line.181"></a>
+<span class="sourceLineNo">182</span>      if (!racksToIndex.containsKey(rack)) {<a name="line.182"></a>
+<span class="sourceLineNo">183</span>        racksToIndex.put(rack, numRacks++);<a name="line.183"></a>
+<span class="sourceLineNo">184</span>        serversPerRackList.add(new ArrayList&lt;&gt;());<a name="line.184"></a>
+<span class="sourceLineNo">185</span>      }<a name="line.185"></a>
+<span class="sourceLineNo">186</span>      int rackIndex = racksToIndex.get(rack);<a name="line.186"></a>
+<span class="sourceLineNo">187</span>      serversPerRackList.get(rackIndex).add(serverIndex);<a name="line.187"></a>
+<span class="sourceLineNo">188</span>    }<a name="line.188"></a>
+<span class="sourceLineNo">189</span><a name="line.189"></a>
+<span class="sourceLineNo">190</span>    // Count how many regions there are.<a name="line.190"></a>
+<span class="sourceLineNo">191</span>    for (Map.Entry&lt;ServerName, List&lt;RegionInfo&gt;&gt; entry : clusterState.entrySet()) {<a name="line.191"></a>
+<span class="sourceLineNo">192</span>      numRegions += entry.getValue().size();<a name="line.192"></a>
+<span class="sourceLineNo">193</span>    }<a name="line.193"></a>
+<span class="sourceLineNo">194</span>    numRegions += unassignedRegions.size();<a name="line.194"></a>
+<span class="sourceLineNo">195</span><a name="line.195"></a>
+<span class="sourceLineNo">196</span>    regionsToIndex = new HashMap&lt;&gt;(numRegions);<a name="line.196"></a>
+<span class="sourceLineNo">197</span>    servers = new ServerName[numServers];<a name="line.197"></a>
+<span class="sourceLineNo">198</span>    serversPerHost = new int[numHosts][];<a name="line.198"></a>
+<span class="sourceLineNo">199</span>    serversPerRack = new int[numRacks][];<a name="line.199"></a>
+<span class="sourceLineNo">200</span>    regions = new RegionInfo[numRegions];<a name="line.200"></a>
+<span class="sourceLineNo">201</span>    regionIndexToServerIndex = new int[numRegions];<a name="line.201"></a>
+<span class="sourceLineNo">202</span>    initialRegionIndexToServerIndex = new int[numRegions];<a name="line.202"></a>
+<span class="sourceLineNo">203</span>    regionIndexToTableIndex = new int[numRegions];<a name="line.203"></a>
+<span class="sourceLineNo">204</span>    regionIndexToPrimaryIndex = new int[numRegions];<a name="line.204"></a>
+<span class="sourceLineNo">205</span>    regionLoads = new Deque[numRegions];<a name="line.205"></a>
+<span class="sourceLineNo">206</span><a name="line.206"></a>
+<span class="sourceLineNo">207</span>    regionLocations = new int[numRegions][];<a name="line.207"></a>
+<span class="sourceLineNo">208</span>    serverIndicesSortedByRegionCount = new Integer[numServers];<a name="line.208"></a>
+<span class="sourceLineNo">209</span>    serverIndicesSortedByLocality = new Integer[numServers];<a name="line.209"></a>
+<span class="sourceLineNo">210</span>    localityPerServer = new float[numServers];<a name="line.210"></a>
+<span class="sourceLineNo">211</span><a name="line.211"></a>
+<span class="sourceLineNo">212</span>    serverIndexToHostIndex = new int[numServers];<a name="line.212"></a>
+<span class="sourceLineNo">213</span>    serverIndexToRackIndex = new int[numServers];<a name="line.213"></a>
+<span class="sourceLineNo">214</span>    regionsPerServer = new int[numServers][];<a name="line.214"></a>
+<span class="sourceLineNo">215</span>    serverIndexToRegionsOffset = new int[numServers];<a name="line.215"></a>
+<span class="sourceLineNo">216</span>    regionsPerHost = new int[numHosts][];<a name="line.216"></a>
+<span class="sourceLineNo">217</span>    regionsPerRack = new int[numRacks][];<a name="line.217"></a>
+<span class="sourceLineNo">218</span>    colocatedReplicaCountsPerServer = new Int2IntCounterMap[numServers];<a name="line.218"></a>
+<span class="sourceLineNo">219</span>    colocatedReplicaCountsPerHost = new Int2IntCounterMap[numHosts];<a name="line.219"></a>
+<span class="sourceLineNo">220</span>    colocatedReplicaCountsPerRack = new Int2IntCounterMap[numRacks];<a name="line.220"></a>
+<span class="sourceLineNo">221</span><a name="line.221"></a>
+<span class="sourceLineNo">222</span>    int tableIndex = 0, regionIndex = 0, regionPerServerIndex = 0;<a name="line.222"></a>
+<span class="sourceLineNo">223</span><a name="line.223"></a>
+<span class="sourceLineNo">224</span>    for (Map.Entry&lt;ServerName, List&lt;RegionInfo&gt;&gt; entry : clusterState.entrySet()) {<a name="line.224"></a>
+<span class="sourceLineNo">225</span>      if (entry.getKey() == null) {<a name="line.225"></a>
+<span class="sourceLineNo">226</span>        LOG.warn("SERVERNAME IS NULL, skipping " + entry.getValue());<a name="line.226"></a>
+<span class="sourceLineNo">227</span>        continue;<a name="line.227"></a>
+<span class="sourceLineNo">228</span>      }<a name="line.228"></a>
+<span class="sourceLineNo">229</span>      int serverIndex = serversToIndex.get(entry.getKey().getAddress());<a name="line.229"></a>
+<span class="sourceLineNo">230</span><a name="line.230"></a>
+<span class="sourceLineNo">231</span>      // keep the servername if this is the first server name for this hostname<a name="line.231"></a>
+<span class="sourceLineNo">232</span>      // or this servername has the newest startcode.<a name="line.232"></a>
+<span class="sourceLineNo">233</span>      if (servers[serverIndex] == null ||<a name="line.233"></a>
+<span class="sourceLineNo">234</span>        servers[serverIndex].getStartcode() &lt; entry.getKey().getStartcode()) {<a name="line.234"></a>
+<span class="sourceLineNo">235</span>        servers[serverIndex] = entry.getKey();<a name="line.235"></a>
+<span class="sourceLineNo">236</span>      }<a name="line.236"></a>
+<span class="sourceLineNo">237</span><a name="line.237"></a>
+<span class="sourceLineNo">238</span>      if (regionsPerServer[serverIndex] != null) {<a name="line.238"></a>
+<span class="sourceLineNo">239</span>        // there is another server with the same hostAndPort in ClusterState.<a name="line.239"></a>
+<span class="sourceLineNo">240</span>        // allocate the array for the total size<a name="line.240"></a>
+<span class="sourceLineNo">241</span>        regionsPerServer[serverIndex] =<a name="line.241"></a>
+<span class="sourceLineNo">242</span>          new int[entry.getValue().size() + regionsPerServer[serverIndex].length];<a name="line.242"></a>
+<span class="sourceLineNo">243</span>      } else {<a name="line.243"></a>
+<span class="sourceLineNo">244</span>        regionsPerServer[serverIndex] = new int[entry.getValue().size()];<a name="line.244"></a>
+<span class="sourceLineNo">245</span>      }<a name="line.245"></a>
+<span class="sourceLineNo">246</span>      colocatedReplicaCountsPerServer[serverIndex] = new Int2IntCounterMap(<a name="line.246"></a>
+<span class="sourceLineNo">247</span>        regionsPerServer[serverIndex].length, Hashing.DEFAULT_LOAD_FACTOR, 0);<a name="line.247"></a>
+<span class="sourceLineNo">248</span>      serverIndicesSortedByRegionCount[serverIndex] = serverIndex;<a name="line.248"></a>
+<span class="sourceLineNo">249</span>      serverIndicesSortedByLocality[serverIndex] = serverIndex;<a name="line.249"></a>
 <span class="sourceLineNo">250</span>    }<a name="line.250"></a>
-<span class="sourceLineNo">251</span>    racks = new String[numRacks];<a name="line.251"></a>
-<span class="sourceLineNo">252</span>    for (Map.Entry&lt;String, Integer&gt; entry : racksToIndex.entrySet()) {<a name="line.252"></a>
-<span class="sourceLineNo">253</span>      racks[entry.getValue()] = entry.getKey();<a name="line.253"></a>
-<span class="sourceLineNo">254</span>    }<a name="line.254"></a>
-<span class="sourceLineNo">255</span><a name="line.255"></a>
-<span class="sourceLineNo">256</span>    for (Map.Entry&lt;ServerName, List&lt;RegionInfo&gt;&gt; entry : clusterState.entrySet()) {<a name="line.256"></a>
-<span class="sourceLineNo">257</span>      int serverIndex = serversToIndex.get(entry.getKey().getAddress());<a name="line.257"></a>
-<span class="sourceLineNo">258</span>      regionPerServerIndex = serverIndexToRegionsOffset[serverIndex];<a name="line.258"></a>
-<span class="sourceLineNo">259</span><a name="line.259"></a>
-<span class="sourceLineNo">260</span>      int hostIndex = hostsToIndex.get(entry.getKey().getHostname());<a name="line.260"></a>
-<span class="sourceLineNo">261</span>      serverIndexToHostIndex[serverIndex] = hostIndex;<a name="line.261"></a>
-<span class="sourceLineNo">262</span><a name="line.262"></a>
-<span class="sourceLineNo">263</span>      int rackIndex = racksToIndex.get(this.rackManager.getRack(entry.getKey()));<a name="line.263"></a>
-<span class="sourceLineNo">264</span>      serverIndexToRackIndex[serverIndex] = rackIndex;<a name="line.264"></a>
-<span class="sourceLineNo">265</span><a name="line.265"></a>
-<span class="sourceLineNo">266</span>      for (RegionInfo region : entry.getValue()) {<a name="line.266"></a>
-<span class="sourceLineNo">267</span>        registerRegion(region, regionIndex, serverIndex, loads, regionFinder);<a name="line.267"></a>
-<span class="sourceLineNo">268</span>        regionsPerServer[serverIndex][regionPerServerIndex++] = regionIndex;<a name="line.268"></a>
-<span class="sourceLineNo">269</span>        regionIndex++;<a name="line.269"></a>
-<span class="sourceLineNo">270</span>      }<a name="line.270"></a>
-<span class="sourceLineNo">271</span>      serverIndexToRegionsOffset[serverIndex] = regionPerServerIndex;<a name="line.271"></a>
-<span class="sourceLineNo">272</span>    }<a name="line.272"></a>
-<span class="sourceLineNo">273</span><a name="line.273"></a>
-<span class="sourceLineNo">274</span>    for (RegionInfo region : unassignedRegions) {<a name="line.274"></a>
-<span class="sourceLineNo">275</span>      registerRegion(region, regionIndex, -1, loads, regionFinder);<a name="line.275"></a>
-<span class="sourceLineNo">276</span>      regionIndex++;<a name="line.276"></a>
+<span class="sourceLineNo">251</span><a name="line.251"></a>
+<span class="sourceLineNo">252</span>    hosts = new String[numHosts];<a name="line.252"></a>
+<span class="sourceLineNo">253</span>    for (Map.Entry&lt;String, Integer&gt; entry : hostsToIndex.entrySet()) {<a name="line.253"></a>
+<span class="sourceLineNo">254</span>      hosts[entry.getValue()] = entry.getKey();<a name="line.254"></a>
+<span class="sourceLineNo">255</span>    }<a name="line.255"></a>
+<span class="sourceLineNo">256</span>    racks = new String[numRacks];<a name="line.256"></a>
+<span class="sourceLineNo">257</span>    for (Map.Entry&lt;String, Integer&gt; entry : racksToIndex.entrySet()) {<a name="line.257"></a>
+<span class="sourceLineNo">258</span>      racks[entry.getValue()] = entry.getKey();<a name="line.258"></a>
+<span class="sourceLineNo">259</span>    }<a name="line.259"></a>
+<span class="sourceLineNo">260</span><a name="line.260"></a>
+<span class="sourceLineNo">261</span>    for (Map.Entry&lt;ServerName, List&lt;RegionInfo&gt;&gt; entry : clusterState.entrySet()) {<a name="line.261"></a>
+<span class="sourceLineNo">262</span>      int serverIndex = serversToIndex.get(entry.getKey().getAddress());<a name="line.262"></a>
+<span class="sourceLineNo">263</span>      regionPerServerIndex = serverIndexToRegionsOffset[serverIndex];<a name="line.263"></a>
+<span class="sourceLineNo">264</span><a name="line.264"></a>
+<span class="sourceLineNo">265</span>      int hostIndex = hostsToIndex.get(entry.getKey().getHostname());<a name="line.265"></a>
+<span class="sourceLineNo">266</span>      serverIndexToHostIndex[serverIndex] = hostIndex;<a name="line.266"></a>
+<span class="sourceLineNo">267</span><a name="line.267"></a>
+<span class="sourceLineNo">268</span>      int rackIndex = racksToIndex.get(this.rackManager.getRack(entry.getKey()));<a name="line.268"></a>
+<span class="sourceLineNo">269</span>      serverIndexToRackIndex[serverIndex] = rackIndex;<a name="line.269"></a>
+<span class="sourceLineNo">270</span><a name="line.270"></a>
+<span class="sourceLineNo">271</span>      for (RegionInfo region : entry.getValue()) {<a name="line.271"></a>
+<span class="sourceLineNo">272</span>        registerRegion(region, regionIndex, serverIndex, loads, regionFinder);<a name="line.272"></a>
+<span class="sourceLineNo">273</span>        regionsPerServer[serverIndex][regionPerServerIndex++] = regionIndex;<a name="line.273"></a>
+<span class="sourceLineNo">274</span>        regionIndex++;<a name="line.274"></a>
+<span class="sourceLineNo">275</span>      }<a name="line.275"></a>
+<span class="sourceLineNo">276</span>      serverIndexToRegionsOffset[serverIndex] = regionPerServerIndex;<a name="line.276"></a>
 <span class="sourceLineNo">277</span>    }<a name="line.277"></a>
 <span class="sourceLineNo">278</span><a name="line.278"></a>
-<span class="sourceLineNo">279</span>    for (int i = 0; i &lt; serversPerHostList.size(); i++) {<a name="line.279"></a>
-<span class="sourceLineNo">280</span>      serversPerHost[i] = new int[serversPerHostList.get(i).size()];<a name="line.280"></a>
-<span class="sourceLineNo">281</span>      for (int j = 0; j &lt; serversPerHost[i].length; j++) {<a name="line.281"></a>
-<span class="sourceLineNo">282</span>        serversPerHost[i][j] = serversPerHostList.get(i).get(j);<a name="line.282"></a>
-<span class="sourceLineNo">283</span>      }<a name="line.283"></a>
-<span class="sourceLineNo">284</span>      if (serversPerHost[i].length &gt; 1) {<a name="line.284"></a>
-<span class="sourceLineNo">285</span>        multiServersPerHost = true;<a name="line.285"></a>
-<span class="sourceLineNo">286</span>      }<a name="line.286"></a>
-<span class="sourceLineNo">287</span>    }<a name="line.287"></a>
-<span class="sourceLineNo">288</span><a name="line.288"></a>
-<span class="sourceLineNo">289</span>    for (int i = 0; i &lt; serversPerRackList.size(); i++) {<a name="line.289"></a>
-<span class="sourceLineNo">290</span>      serversPerRack[i] = new int[serversPerRackList.get(i).size()];<a name="line.290"></a>
-<span class="sourceLineNo">291</span>      for (int j = 0; j &lt; serversPerRack[i].length; j++) {<a name="line.291"></a>
-<span class="sourceLineNo">292</span>        serversPerRack[i][j] = serversPerRackList.get(i).get(j);<a name="line.292"></a>
-<span class="sourceLineNo">293</span>      }<a name="line.293"></a>
-<span class="sourceLineNo">294</span>    }<a name="line.294"></a>
-<span class="sourceLineNo">295</span><a name="line.295"></a>
-<span class="sourceLineNo">296</span>    numTables = tables.size();<a name="line.296"></a>
-<span class="sourceLineNo">297</span>    LOG.debug("Number of tables={}", numTables);<a name="line.297"></a>
-<span class="sourceLineNo">298</span>    numRegionsPerServerPerTable = new int[numServers][numTables];<a name="line.298"></a>
-<span class="sourceLineNo">299</span>    numRegionsPerTable = new int[numTables];<a name="line.299"></a>
+<span class="sourceLineNo">279</span>    for (RegionInfo region : unassignedRegions) {<a name="line.279"></a>
+<span class="sourceLineNo">280</span>      registerRegion(region, regionIndex, -1, loads, regionFinder);<a name="line.280"></a>
+<span class="sourceLineNo">281</span>      regionIndex++;<a name="line.281"></a>
+<span class="sourceLineNo">282</span>    }<a name="line.282"></a>
+<span class="sourceLineNo">283</span><a name="line.283"></a>
+<span class="sourceLineNo">284</span>    for (int i = 0; i &lt; serversPerHostList.size(); i++) {<a name="line.284"></a>
+<span class="sourceLineNo">285</span>      serversPerHost[i] = new int[serversPerHostList.get(i).size()];<a name="line.285"></a>
+<span class="sourceLineNo">286</span>      for (int j = 0; j &lt; serversPerHost[i].length; j++) {<a name="line.286"></a>
+<span class="sourceLineNo">287</span>        serversPerHost[i][j] = serversPerHostList.get(i).get(j);<a name="line.287"></a>
+<span class="sourceLineNo">288</span>      }<a name="line.288"></a>
+<span class="sourceLineNo">289</span>      if (serversPerHost[i].length &gt; 1) {<a name="line.289"></a>
+<span class="sourceLineNo">290</span>        multiServersPerHost = true;<a name="line.290"></a>
+<span class="sourceLineNo">291</span>      }<a name="line.291"></a>
+<span class="sourceLineNo">292</span>    }<a name="line.292"></a>
+<span class="sourceLineNo">293</span><a name="line.293"></a>
+<span class="sourceLineNo">294</span>    for (int i = 0; i &lt; serversPerRackList.size(); i++) {<a name="line.294"></a>
+<span class="sourceLineNo">295</span>      serversPerRack[i] = new int[serversPerRackList.get(i).size()];<a name="line.295"></a>
+<span class="sourceLineNo">296</span>      for (int j = 0; j &lt; serversPerRack[i].length; j++) {<a name="line.296"></a>
+<span class="sourceLineNo">297</span>        serversPerRack[i][j] = serversPerRackList.get(i).get(j);<a name="line.297"></a>
+<span class="sourceLineNo">298</span>      }<a name="line.298"></a>
+<span class="sourceLineNo">299</span>    }<a name="line.299"></a>
 <span class="sourceLineNo">300</span><a name="line.300"></a>
-<span class="sourceLineNo">301</span>    for (int i = 0; i &lt; numServers; i++) {<a name="line.301"></a>
-<span class="sourceLineNo">302</span>      for (int j = 0; j &lt; numTables; j++) {<a name="line.302"></a>
-<span class="sourceLineNo">303</span>        numRegionsPerServerPerTable[i][j] = 0;<a name="line.303"></a>
-<span class="sourceLineNo">304</span>      }<a name="line.304"></a>
-<span class="sourceLineNo">305</span>    }<a name="line.305"></a>
-<span class="sourceLineNo">306</span><a name="line.306"></a>
-<span class="sourceLineNo">307</span>    for (int i = 0; i &lt; regionIndexToServerIndex.length; i++) {<a name="line.307"></a>
-<span class="sourceLineNo">308</span>      if (regionIndexToServerIndex[i] &gt;= 0) {<a name="line.308"></a>
-<span class="sourceLineNo">309</span>        numRegionsPerServerPerTable[regionIndexToServerIndex[i]][regionIndexToTableIndex[i]]++;<a name="line.309"></a>
-<span class="sourceLineNo">310</span>        numRegionsPerTable[regionIndexToTableIndex[i]]++;<a name="line.310"></a>
-<span class="sourceLineNo">311</span>      }<a name="line.311"></a>
-<span class="sourceLineNo">312</span>    }<a name="line.312"></a>
-<span class="sourceLineNo">313</span><a name="line.313"></a>
-<span class="sourceLineNo">314</span>    // Avoid repeated computation for planning<a name="line.314"></a>
-<span class="sourceLineNo">315</span>    meanRegionsPerTable = new double[numTables];<a name="line.315"></a>
-<span class="sourceLineNo">316</span>    regionSkewByTable = new double[numTables];<a name="line.316"></a>
-<span class="sourceLineNo">317</span>    maxRegionSkewByTable  = new double[numTables];<a name="line.317"></a>
-<span class="sourceLineNo">318</span>    minRegionSkewByTable = new double[numTables];<a name="line.318"></a>
-<span class="sourceLineNo">319</span><a name="line.319"></a>
-<span class="sourceLineNo">320</span>    for (int i = 0; i &lt; numTables; i++) {<a name="line.320"></a>
-<span class="sourceLineNo">321</span>      meanRegionsPerTable[i] = Double.valueOf(numRegionsPerTable[i]) / numServers;<a name="line.321"></a>
-<span class="sourceLineNo">322</span>      minRegionSkewByTable[i] += DoubleArrayCost.getMinSkew(numRegionsPerTable[i], numServers);<a name="line.322"></a>
-<span class="sourceLineNo">323</span>      maxRegionSkewByTable[i] += DoubleArrayCost.getMaxSkew(numRegionsPerTable[i], numServers);<a name="line.323"></a>
-<span class="sourceLineNo">324</span>    }<a name="line.324"></a>
-<span class="sourceLineNo">325</span><a name="line.325"></a>
-<span class="sourceLineNo">326</span>    for (int[] aNumRegionsPerServerPerTable : numRegionsPerServerPerTable) {<a name="line.326"></a>
-<span class="sourceLineNo">327</span>      for (int tableIdx = 0; tableIdx &lt; aNumRegionsPerServerPerTable.length; tableIdx++) {<a name="line.327"></a>
-<span class="sourceLineNo">328</span>        regionSkewByTable[tableIdx] += Math.abs(aNumRegionsPerServerPerTable[tableIdx] -<a name="line.328"></a>
-<span class="sourceLineNo">329</span>          meanRegionsPerTable[tableIdx]);<a name="line.329"></a>
-<span class="sourceLineNo">330</span>      }<a name="line.330"></a>
-<span class="sourceLineNo">331</span>    }<a name="line.331"></a>
-<span class="sourceLineNo">332</span><a name="line.332"></a>
-<span class="sourceLineNo">333</span>    for (int i = 0; i &lt; regions.length; i++) {<a name="line.333"></a>
-<span class="sourceLineNo">334</span>      RegionInfo info = regions[i];<a name="line.334"></a>
-<span class="sourceLineNo">335</span>      if (RegionReplicaUtil.isDefaultReplica(info)) {<a name="line.335"></a>
-<span class="sourceLineNo">336</span>        regionIndexToPrimaryIndex[i] = i;<a name="line.336"></a>
-<span class="sourceLineNo">337</span>      } else {<a name="line.337"></a>
-<span class="sourceLineNo">338</span>        hasRegionReplicas = true;<a name="line.338"></a>
-<span class="sourceLineNo">339</span>        RegionInfo primaryInfo = RegionReplicaUtil.getRegionInfoForDefaultReplica(info);<a name="line.339"></a>
-<span class="sourceLineNo">340</span>        regionIndexToPrimaryIndex[i] = regionsToIndex.getOrDefault(primaryInfo, -1);<a name="line.340"></a>
-<span class="sourceLineNo">341</span>      }<a name="line.341"></a>
-<span class="sourceLineNo">342</span>    }<a name="line.342"></a>
-<span class="sourceLineNo">343</span><a name="line.343"></a>
-<span class="sourceLineNo">344</span>    for (int i = 0; i &lt; regionsPerServer.length; i++) {<a name="line.344"></a>
-<span class="sourceLineNo">345</span>      primariesOfRegionsPerServer[i] = new int[regionsPerServer[i].length];<a name="line.345"></a>
-<span class="sourceLineNo">346</span>      for (int j = 0; j &lt; regionsPerServer[i].length; j++) {<a name="line.346"></a>
-<span class="sourceLineNo">347</span>        int primaryIndex = regionIndexToPrimaryIndex[regionsPerServer[i][j]];<a name="line.347"></a>
-<span class="sourceLineNo">348</span>        primariesOfRegionsPerServer[i][j] = primaryIndex;<a name="line.348"></a>
-<span class="sourceLineNo">349</span>      }<a name="line.349"></a>
-<span class="sourceLineNo">350</span>      // sort the regions by primaries.<a name="line.350"></a>
-<span class="sourceLineNo">351</span>      Arrays.sort(primariesOfRegionsPerServer[i]);<a name="line.351"></a>
-<span class="sourceLineNo">352</span>    }<a name="line.352"></a>
-<span class="sourceLineNo">353</span><a name="line.353"></a>
-<span class="sourceLineNo">354</span>    // compute regionsPerHost<a name="line.354"></a>
-<span class="sourceLineNo">355</span>    if (multiServersPerHost) {<a name="line.355"></a>
-<span class="sourceLineNo">356</span>      for (int i = 0; i &lt; serversPerHost.length; i++) {<a name="line.356"></a>
-<span class="sourceLineNo">357</span>        int numRegionsPerHost = 0;<a name="line.357"></a>
-<span class="sourceLineNo">358</span>        for (int j = 0; j &lt; serversPerHost[i].length; j++) {<a name="line.358"></a>
-<span class="sourceLineNo">359</span>          numRegionsPerHost += regionsPerServer[serversPerHost[i][j]].length;<a name="line.359"></a>
-<span class="sourceLineNo">360</span>        }<a name="line.360"></a>
-<span class="sourceLineNo">361</span>        regionsPerHost[i] = new int[numRegionsPerHost];<a name="line.361"></a>
-<span class="sourceLineNo">362</span>        primariesOfRegionsPerHost[i] = new int[numRegionsPerHost];<a name="line.362"></a>
-<span class="sourceLineNo">363</span>      }<a name="line.363"></a>
-<span class="sourceLineNo">364</span>      for (int i = 0; i &lt; serversPerHost.length; i++) {<a name="line.364"></a>
-<span class="sourceLineNo">365</span>        int numRegionPerHostIndex = 0;<a name="line.365"></a>
-<span class="sourceLineNo">366</span>        for (int j = 0; j &lt; serversPerHost[i].length; j++) {<a name="line.366"></a>
-<span class="sourceLineNo">367</span>          for (int k = 0; k &lt; regionsPerServer[serversPerHost[i][j]].length; k++) {<a name="line.367"></a>
-<span class="sourceLineNo">368</span>            int region = regionsPerServer[serversPerHost[i][j]][k];<a name="line.368"></a>
-<span class="sourceLineNo">369</span>            regionsPerHost[i][numRegionPerHostIndex] = region;<a name="line.369"></a>
-<span class="sourceLineNo">370</span>            int primaryIndex = regionIndexToPrimaryIndex[region];<a name="line.370"></a>
-<span class="sourceLineNo">371</span>            primariesOfRegionsPerHost[i][numRegionPerHostIndex] = primaryIndex;<a name="line.371"></a>
-<span class="sourceLineNo">372</span>            numRegionPerHostIndex++;<a name="line.372"></a>
-<span class="sourceLineNo">373</span>          }<a name="line.373"></a>
-<span class="sourceLineNo">374</span>        }<a name="line.374"></a>
-<span class="sourceLineNo">375</span>        // sort the regions by primaries.<a name="line.375"></a>
-<span class="sourceLineNo">376</span>        Arrays.sort(primariesOfRegionsPerHost[i]);<a name="line.376"></a>
+<span class="sourceLineNo">301</span>    numTables = tables.size();<a name="line.301"></a>
+<span class="sourceLineNo">302</span>    LOG.debug("Number of tables={}", numTables);<a name="line.302"></a>
+<span class="sourceLineNo">303</span>    numRegionsPerServerPerTable = new int[numServers][numTables];<a name="line.303"></a>
+<span class="sourceLineNo">304</span>    numRegionsPerTable = new int[numTables];<a name="line.304"></a>
+<span class="sourceLineNo">305</span><a name="line.305"></a>
+<span class="sourceLineNo">306</span>    for (int i = 0; i &lt; numServers; i++) {<a name="line.306"></a>
+<span class="sourceLineNo">307</span>      for (int j = 0; j &lt; numTables; j++) {<a name="line.307"></a>
+<span class="sourceLineNo">308</span>        numRegionsPerServerPerTable[i][j] = 0;<a name="line.308"></a>
+<span class="sourceLineNo">309</span>      }<a name="line.309"></a>
+<span class="sourceLineNo">310</span>    }<a name="line.310"></a>
+<span class="sourceLineNo">311</span><a name="line.311"></a>
+<span class="sourceLineNo">312</span>    for (int i = 0; i &lt; regionIndexToServerIndex.length; i++) {<a name="line.312"></a>
+<span class="sourceLineNo">313</span>      if (regionIndexToServerIndex[i] &gt;= 0) {<a name="line.313"></a>
+<span class="sourceLineNo">314</span>        numRegionsPerServerPerTable[regionIndexToServerIndex[i]][regionIndexToTableIndex[i]]++;<a name="line.314"></a>
+<span class="sourceLineNo">315</span>        numRegionsPerTable[regionIndexToTableIndex[i]]++;<a name="line.315"></a>
+<span class="sourceLineNo">316</span>      }<a name="line.316"></a>
+<span class="sourceLineNo">317</span>    }<a name="line.317"></a>
+<span class="sourceLineNo">318</span><a name="line.318"></a>
+<span class="sourceLineNo">319</span>    // Avoid repeated computation for planning<a name="line.319"></a>
+<span class="sourceLineNo">320</span>    meanRegionsPerTable = new double[numTables];<a name="line.320"></a>
+<span class="sourceLineNo">321</span>    regionSkewByTable = new double[numTables];<a name="line.321"></a>
+<span class="sourceLineNo">322</span>    maxRegionSkewByTable  = new double[numTables];<a name="line.322"></a>
+<span class="sourceLineNo">323</span>    minRegionSkewByTable = new double[numTables];<a name="line.323"></a>
+<span class="sourceLineNo">324</span><a name="line.324"></a>
+<span class="sourceLineNo">325</span>    for (int i = 0; i &lt; numTables; i++) {<a name="line.325"></a>
+<span class="sourceLineNo">326</span>      meanRegionsPerTable[i] = Double.valueOf(numRegionsPerTable[i]) / numServers;<a name="line.326"></a>
+<span class="sourceLineNo">327</span>      minRegionSkewByTable[i] += DoubleArrayCost.getMinSkew(numRegionsPerTable[i], numServers);<a name="line.327"></a>
+<span class="sourceLineNo">328</span>      maxRegionSkewByTable[i] += DoubleArrayCost.getMaxSkew(numRegionsPerTable[i], numServers);<a name="line.328"></a>
+<span class="sourceLineNo">329</span>    }<a name="line.329"></a>
+<span class="sourceLineNo">330</span><a name="line.330"></a>
+<span class="sourceLineNo">331</span>    for (int[] aNumRegionsPerServerPerTable : numRegionsPerServerPerTable) {<a name="line.331"></a>
+<span class="sourceLineNo">332</span>      for (int tableIdx = 0; tableIdx &lt; aNumRegionsPerServerPerTable.length; tableIdx++) {<a name="line.332"></a>
+<span class="sourceLineNo">333</span>        regionSkewByTable[tableIdx] += Math.abs(aNumRegionsPerServerPerTable[tableIdx] -<a name="line.333"></a>
+<span class="sourceLineNo">334</span>          meanRegionsPerTable[tableIdx]);<a name="line.334"></a>
+<span class="sourceLineNo">335</span>      }<a name="line.335"></a>
+<span class="sourceLineNo">336</span>    }<a name="line.336"></a>
+<span class="sourceLineNo">337</span><a name="line.337"></a>
+<span class="sourceLineNo">338</span>    for (int i = 0; i &lt; regions.length; i++) {<a name="line.338"></a>
+<span class="sourceLineNo">339</span>      RegionInfo info = regions[i];<a name="line.339"></a>
+<span class="sourceLineNo">340</span>      if (RegionReplicaUtil.isDefaultReplica(info)) {<a name="line.340"></a>
+<span class="sourceLineNo">341</span>        regionIndexToPrimaryIndex[i] = i;<a name="line.341"></a>
+<span class="sourceLineNo">342</span>      } else {<a name="line.342"></a>
+<span class="sourceLineNo">343</span>        hasRegionReplicas = true;<a name="line.343"></a>
+<span class="sourceLineNo">344</span>        RegionInfo primaryInfo = RegionReplicaUtil.getRegionInfoForDefaultReplica(info);<a name="line.344"></a>
+<span class="sourceLineNo">345</span>        regionIndexToPrimaryIndex[i] = regionsToIndex.getOrDefault(primaryInfo, -1);<a name="line.345"></a>
+<span class="sourceLineNo">346</span>      }<a name="line.346"></a>
+<span class="sourceLineNo">347</span>    }<a name="line.347"></a>
+<span class="sourceLineNo">348</span><a name="line.348"></a>
+<span class="sourceLineNo">349</span>    for (int i = 0; i &lt; regionsPerServer.length; i++) {<a name="line.349"></a>
+<span class="sourceLineNo">350</span>      colocatedReplicaCountsPerServer[i] = new Int2IntCounterMap(<a name="line.350"></a>
+<span class="sourceLineNo">351</span>        regionsPerServer[i].length, Hashing.DEFAULT_LOAD_FACTOR, 0);<a name="line.351"></a>
+<span class="sourceLineNo">352</span>      for (int j = 0; j &lt; regionsPerServer[i].length; j++) {<a name="line.352"></a>
+<span class="sourceLineNo">353</span>        int primaryIndex = regionIndexToPrimaryIndex[regionsPerServer[i][j]];<a name="line.353"></a>
+<span class="sourceLineNo">354</span>        colocatedReplicaCountsPerServer[i].getAndIncrement(primaryIndex);<a name="line.354"></a>
+<span class="sourceLineNo">355</span>      }<a name="line.355"></a>
+<span class="sourceLineNo">356</span>    }<a name="line.356"></a>
+<span class="sourceLineNo">357</span>    // compute regionsPerHost<a name="line.357"></a>
+<span class="sourceLineNo">358</span>    if (multiServersPerHost) {<a name="line.358"></a>
+<span class="sourceLineNo">359</span>      populateRegionPerLocationFromServer(regionsPerHost, colocatedReplicaCountsPerHost,<a name="line.359"></a>
+<span class="sourceLineNo">360</span>        serversPerHost);<a name="line.360"></a>
+<span class="sourceLineNo">361</span>    }<a name="line.361"></a>
+<span class="sourceLineNo">362</span><a name="line.362"></a>
+<span class="sourceLineNo">363</span>    // compute regionsPerRack<a name="line.363"></a>
+<span class="sourceLineNo">364</span>    if (numRacks &gt; 1) {<a name="line.364"></a>
+<span class="sourceLineNo">365</span>      populateRegionPerLocationFromServer(regionsPerRack, colocatedReplicaCountsPerRack,<a name="line.365"></a>
+<span class="sourceLineNo">366</span>        serversPerRack);<a name="line.366"></a>
+<span class="sourceLineNo">367</span>    }<a name="line.367"></a>
+<span class="sourceLineNo">368</span>  }<a name="line.368"></a>
+<span class="sourceLineNo">369</span><a name="line.369"></a>
+<span class="sourceLineNo">370</span>  private void populateRegionPerLocationFromServer(int[][] regionsPerLocation,<a name="line.370"></a>
+<span class="sourceLineNo">371</span>    Int2IntCounterMap[] colocatedReplicaCountsPerLocation,<a name="line.371"></a>
+<span class="sourceLineNo">372</span>    int[][] serversPerLocation) {<a name="line.372"></a>
+<span class="sourceLineNo">373</span>    for (int i = 0; i &lt; serversPerLocation.length; i++) {<a name="line.373"></a>
+<span class="sourceLineNo">374</span>      int numRegionsPerLocation = 0;<a name="line.374"></a>
+<span class="sourceLineNo">375</span>      for (int j = 0; j &lt; serversPerLocation[i].length; j++) {<a name="line.375"></a>
+<span class="sourceLineNo">376</span>        numRegionsPerLocation += regionsPerServer[serversPerLocation[i][j]].length;<a name="line.376"></a>
 <span class="sourceLineNo">377</span>      }<a name="line.377"></a>
-<span class="sourceLineNo">378</span>    }<a name="line.378"></a>
-<span class="sourceLineNo">379</span><a name="line.379"></a>
-<span class="sourceLineNo">380</span>    // compute regionsPerRack<a name="line.380"></a>
-<span class="sourceLineNo">381</span>    if (numRacks &gt; 1) {<a name="line.381"></a>
-<span class="sourceLineNo">382</span>      for (int i = 0; i &lt; serversPerRack.length; i++) {<a name="line.382"></a>
-<span class="sourceLineNo">383</span>        int numRegionsPerRack = 0;<a name="line.383"></a>
-<span class="sourceLineNo">384</span>        for (int j = 0; j &lt; serversPerRack[i].length; j++) {<a name="line.384"></a>
-<span class="sourceLineNo">385</span>          numRegionsPerRack += regionsPerServer[serversPerRack[i][j]].length;<a name="line.385"></a>
-<span class="sourceLineNo">386</span>        }<a name="line.386"></a>
-<span class="sourceLineNo">387</span>        regionsPerRack[i] = new int[numRegionsPerRack];<a name="line.387"></a>
-<span class="sourceLineNo">388</span>        primariesOfRegionsPerRack[i] = new int[numRegionsPerRack];<a name="line.388"></a>
-<span class="sourceLineNo">389</span>      }<a name="line.389"></a>
-<span class="sourceLineNo">390</span><a name="line.390"></a>
-<span class="sourceLineNo">391</span>      for (int i = 0; i &lt; serversPerRack.length; i++) {<a name="line.391"></a>
-<span class="sourceLineNo">392</span>        int numRegionPerRackIndex = 0;<a name="line.392"></a>
-<span class="sourceLineNo">393</span>        for (int j = 0; j &lt; serversPerRack[i].length; j++) {<a name="line.393"></a>
-<span class="sourceLineNo">394</span>          for (int k = 0; k &lt; regionsPerServer[serversPerRack[i][j]].length; k++) {<a name="line.394"></a>
-<span class="sourceLineNo">395</span>            int region = regionsPerServer[serversPerRack[i][j]][k];<a name="line.395"></a>
-<span class="sourceLineNo">396</span>            regionsPerRack[i][numRegionPerRackIndex] = region;<a name="line.396"></a>
-<span class="sourceLineNo">397</span>            int primaryIndex = regionIndexToPrimaryIndex[region];<a name="line.397"></a>
-<span class="sourceLineNo">398</span>            primariesOfRegionsPerRack[i][numRegionPerRackIndex] = primaryIndex;<a name="line.398"></a>
-<span class="sourceLineNo">399</span>            numRegionPerRackIndex++;<a name="line.399"></a>
-<span class="sourceLineNo">400</span>          }<a name="line.400"></a>
-<span class="sourceLineNo">401</span>        }<a name="line.401"></a>
-<span class="sourceLineNo">402</span>        // sort the regions by primaries.<a name="line.402"></a>
-<span class="sourceLineNo">403</span>        Arrays.sort(primariesOfRegionsPerRack[i]);<a name="line.403"></a>
-<span class="sourceLineNo">404</span>      }<a name="line.404"></a>
+<span class="sourceLineNo">378</span>      regionsPerLocation[i] = new int[numRegionsPerLocation];<a name="line.378"></a>
+<span class="sourceLineNo">379</span>      colocatedReplicaCountsPerLocation[i] = new Int2IntCounterMap(numRegionsPerLocation,<a name="line.379"></a>
+<span class="sourceLineNo">380</span>        Hashing.DEFAULT_LOAD_FACTOR, 0);<a name="line.380"></a>
+<span class="sourceLineNo">381</span>    }<a name="line.381"></a>
+<span class="sourceLineNo">382</span><a name="line.382"></a>
+<span class="sourceLineNo">383</span>    for (int i = 0; i &lt; serversPerLocation.length; i++) {<a name="line.383"></a>
+<span class="sourceLineNo">384</span>      int numRegionPerLocationIndex = 0;<a name="line.384"></a>
+<span class="sourceLineNo">385</span>      for (int j = 0; j &lt; serversPerLocation[i].length; j++) {<a name="line.385"></a>
+<span class="sourceLineNo">386</span>        for (int k = 0; k &lt; regionsPerServer[serversPerLocation[i][j]].length; k++) {<a name="line.386"></a>
+<span class="sourceLineNo">387</span>          int region = regionsPerServer[serversPerLocation[i][j]][k];<a name="line.387"></a>
+<span class="sourceLineNo">388</span>          regionsPerLocation[i][numRegionPerLocationIndex] = region;<a name="line.388"></a>
+<span class="sourceLineNo">389</span>          int primaryIndex = regionIndexToPrimaryIndex[region];<a name="line.389"></a>
+<span class="sourceLineNo">390</span>          colocatedReplicaCountsPerLocation[i].getAndIncrement(primaryIndex);<a name="line.390"></a>
+<span class="sourceLineNo">391</span>          numRegionPerLocationIndex++;<a name="line.391"></a>
+<span class="sourceLineNo">392</span>        }<a name="line.392"></a>
+<span class="sourceLineNo">393</span>      }<a name="line.393"></a>
+<span class="sourceLineNo">394</span>    }<a name="line.394"></a>
+<span class="sourceLineNo">395</span><a name="line.395"></a>
+<span class="sourceLineNo">396</span>  }<a name="line.396"></a>
+<span class="sourceLineNo">397</span><a name="line.397"></a>
+<span class="sourceLineNo">398</span>  /** Helper for Cluster constructor to handle a region */<a name="line.398"></a>
+<span class="sourceLineNo">399</span>  private void registerRegion(RegionInfo region, int regionIndex, int serverIndex,<a name="line.399"></a>
+<span class="sourceLineNo">400</span>    Map&lt;String, Deque&lt;BalancerRegionLoad&gt;&gt; loads, RegionHDFSBlockLocationFinder regionFinder) {<a name="line.400"></a>
+<span class="sourceLineNo">401</span>    String tableName = region.getTable().getNameAsString();<a name="line.401"></a>
+<span class="sourceLineNo">402</span>    if (!tablesToIndex.containsKey(tableName)) {<a name="line.402"></a>
+<span class="sourceLineNo">403</span>      tables.add(tableName);<a name="line.403"></a>
+<span class="sourceLineNo">404</span>      tablesToIndex.put(tableName, tablesToIndex.size());<a name="line.404"></a>
 <span class="sourceLineNo">405</span>    }<a name="line.405"></a>
-<span class="sourceLineNo">406</span>  }<a name="line.406"></a>
+<span class="sourceLineNo">406</span>    int tableIndex = tablesToIndex.get(tableName);<a name="line.406"></a>
 <span class="sourceLineNo">407</span><a name="line.407"></a>
-<span class="sourceLineNo">408</span>  /** Helper for Cluster constructor to handle a region */<a name="line.408"></a>
-<span class="sourceLineNo">409</span>  private void registerRegion(RegionInfo region, int regionIndex, int serverIndex,<a name="line.409"></a>
-<span class="sourceLineNo">410</span>    Map&lt;String, Deque&lt;BalancerRegionLoad&gt;&gt; loads, RegionHDFSBlockLocationFinder regionFinder) {<a name="line.410"></a>
-<span class="sourceLineNo">411</span>    String tableName = region.getTable().getNameAsString();<a name="line.411"></a>
-<span class="sourceLineNo">412</span>    if (!tablesToIndex.containsKey(tableName)) {<a name="line.412"></a>
-<span class="sourceLineNo">413</span>      tables.add(tableName);<a name="line.413"></a>
-<span class="sourceLineNo">414</span>      tablesToIndex.put(tableName, tablesToIndex.size());<a name="line.414"></a>
-<span class="sourceLineNo">415</span>    }<a name="line.415"></a>
-<span class="sourceLineNo">416</span>    int tableIndex = tablesToIndex.get(tableName);<a name="line.416"></a>
-<span class="sourceLineNo">417</span><a name="line.417"></a>
-<span class="sourceLineNo">418</span>    regionsToIndex.put(region, regionIndex);<a name="line.418"></a>
-<span class="sourceLineNo">419</span>    regions[regionIndex] = region;<a name="line.419"></a>
-<span class="sourceLineNo">420</span>    regionIndexToServerIndex[regionIndex] = serverIndex;<a name="line.420"></a>
-<span class="sourceLineNo">421</span>    initialRegionIndexToServerIndex[regionIndex] = serverIndex;<a name="line.421"></a>
-<span class="sourceLineNo">422</span>    regionIndexToTableIndex[regionIndex] = tableIndex;<a name="line.422"></a>
-<span class="sourceLineNo">423</span><a name="line.423"></a>
-<span class="sourceLineNo">424</span>    // region load<a name="line.424"></a>
-<span class="sourceLineNo">425</span>    if (loads != null) {<a name="line.425"></a>
-<span class="sourceLineNo">426</span>      Deque&lt;BalancerRegionLoad&gt; rl = loads.get(region.getRegionNameAsString());<a name="line.426"></a>
-<span class="sourceLineNo">427</span>      // That could have failed if the RegionLoad is using the other regionName<a name="line.427"></a>
-<span class="sourceLineNo">428</span>      if (rl == null) {<a name="line.428"></a>
-<span class="sourceLineNo">429</span>        // Try getting the region load using encoded name.<a name="line.429"></a>
-<span class="sourceLineNo">430</span>        rl = loads.get(region.getEncodedName());<a name="line.430"></a>
-<span class="sourceLineNo">431</span>      }<a name="line.431"></a>
-<span class="sourceLineNo">432</span>      regionLoads[regionIndex] = rl;<a name="line.432"></a>
-<span class="sourceLineNo">433</span>    }<a name="line.433"></a>
-<span class="sourceLineNo">434</span><a name="line.434"></a>
-<span class="sourceLineNo">435</span>    if (regionFinder != null) {<a name="line.435"></a>
-<span class="sourceLineNo">436</span>      // region location<a name="line.436"></a>
-<span class="sourceLineNo">437</span>      List&lt;ServerName&gt; loc = regionFinder.getTopBlockLocations(region);<a name="line.437"></a>
-<span class="sourceLineNo">438</span>      regionLocations[regionIndex] = new int[loc.size()];<a name="line.438"></a>
-<span class="sourceLineNo">439</span>      for (int i = 0; i &lt; loc.size(); i++) {<a name="line.439"></a>
-<span class="sourceLineNo">440</span>        regionLocations[regionIndex][i] = loc.get(i) == null ? -1 :<a name="line.440"></a>
-<span class="sourceLineNo">441</span>          (serversToIndex.get(loc.get(i).getAddress()) == null ? -1 :<a name="line.441"></a>
-<span class="sourceLineNo">442</span>            serversToIndex.get(loc.get(i).getAddress()));<a name="line.442"></a>
-<span class="sourceLineNo">443</span>      }<a name="line.443"></a>
-<span class="sourceLineNo">444</span>    }<a name="line.444"></a>
-<span class="sourceLineNo">445</span>  }<a name="line.445"></a>
-<span class="sourceLineNo">446</span><a name="line.446"></a>
-<span class="sourceLineNo">447</span>  /**<a name="line.447"></a>
-<span class="sourceLineNo">448</span>   * Returns true iff a given server has less regions than the balanced amount<a name="line.448"></a>
+<span class="sourceLineNo">408</span>    regionsToIndex.put(region, regionIndex);<a name="line.408"></a>
+<span class="sourceLineNo">409</span>    regions[regionIndex] = region;<a name="line.409"></a>
+<span class="sourceLineNo">410</span>    regionIndexToServerIndex[regionIndex] = serverIndex;<a name="line.410"></a>
+<span class="sourceLineNo">411</span>    initialRegionIndexToServerIndex[regionIndex] = serverIndex;<a name="line.411"></a>
+<span class="sourceLineNo">412</span>    regionIndexToTableIndex[regionIndex] = tableIndex;<a name="line.412"></a>
+<span class="sourceLineNo">413</span><a name="line.413"></a>
+<span class="sourceLineNo">414</span>    // region load<a name="line.414"></a>
+<span class="sourceLineNo">415</span>    if (loads != null) {<a name="line.415"></a>
+<span class="sourceLineNo">416</span>      Deque&lt;BalancerRegionLoad&gt; rl = loads.get(region.getRegionNameAsString());<a name="line.416"></a>
+<span class="sourceLineNo">417</span>      // That could have failed if the RegionLoad is using the other regionName<a name="line.417"></a>
+<span class="sourceLineNo">418</span>      if (rl == null) {<a name="line.418"></a>
+<span class="sourceLineNo">419</span>        // Try getting the region load using encoded name.<a name="line.419"></a>
+<span class="sourceLineNo">420</span>        rl = loads.get(region.getEncodedName());<a name="line.420"></a>
+<span class="sourceLineNo">421</span>      }<a name="line.421"></a>
+<span class="sourceLineNo">422</span>      regionLoads[regionIndex] = rl;<a name="line.422"></a>
+<span class="sourceLineNo">423</span>    }<a name="line.423"></a>
+<span class="sourceLineNo">424</span><a name="line.424"></a>
+<span class="sourceLineNo">425</span>    if (regionFinder != null) {<a name="line.425"></a>
+<span class="sourceLineNo">426</span>      // region location<a name="line.426"></a>
+<span class="sourceLineNo">427</span>      List&lt;ServerName&gt; loc = regionFinder.getTopBlockLocations(region);<a name="line.427"></a>
+<span class="sourceLineNo">428</span>      regionLocations[regionIndex] = new int[loc.size()];<a name="line.428"></a>
+<span class="sourceLineNo">429</span>      for (int i = 0; i &lt; loc.size(); i++) {<a name="line.429"></a>
+<span class="sourceLineNo">430</span>        regionLocations[regionIndex][i] = loc.get(i) == null ? -1 :<a name="line.430"></a>
+<span class="sourceLineNo">431</span>          (serversToIndex.get(loc.get(i).getAddress()) == null ? -1 :<a name="line.431"></a>
+<span class="sourceLineNo">432</span>            serversToIndex.get(loc.get(i).getAddress()));<a name="line.432"></a>
+<span class="sourceLineNo">433</span>      }<a name="line.433"></a>
+<span class="sourceLineNo">434</span>    }<a name="line.434"></a>
+<span class="sourceLineNo">435</span>  }<a name="line.435"></a>
+<span class="sourceLineNo">436</span><a name="line.436"></a>
+<span class="sourceLineNo">437</span>  /**<a name="line.437"></a>
+<span class="sourceLineNo">438</span>   * Returns true iff a given server has less regions than the balanced amount<a name="line.438"></a>
+<span class="sourceLineNo">439</span>   */<a name="line.439"></a>
+<span class="sourceLineNo">440</span>  public boolean serverHasTooFewRegions(int server) {<a name="line.440"></a>
+<span class="sourceLineNo">441</span>    int minLoad = this.numRegions / numServers;<a name="line.441"></a>
+<span class="sourceLineNo">442</span>    int numRegions = getNumRegions(server);<a name="line.442"></a>
+<span class="sourceLineNo">443</span>    return numRegions &lt; minLoad;<a name="line.443"></a>
+<span class="sourceLineNo">444</span>  }<a name="line.444"></a>
+<span class="sourceLineNo">445</span><a name="line.445"></a>
+<span class="sourceLineNo">446</span>  /**<a name="line.446"></a>
+<span class="sourceLineNo">447</span>   * Retrieves and lazily initializes a field storing the locality of every region/server<a name="line.447"></a>
+<span class="sourceLineNo">448</span>   * combination<a name="line.448"></a>
 <span class="sourceLineNo">449</span>   */<a name="line.449"></a>
-<span class="sourceLineNo">450</span>  public boolean serverHasTooFewRegions(int server) {<a name="line.450"></a>
-<span class="sourceLineNo">451</span>    int minLoad = this.numRegions / numServers;<a name="line.451"></a>
-<span class="sourceLineNo">452</span>    int numRegions = getNumRegions(server);<a name="line.452"></a>
-<span class="sourceLineNo">453</span>    return numRegions &lt; minLoad;<a name="line.453"></a>
-<span class="sourceLineNo">454</span>  }<a name="line.454"></a>
-<span class="sourceLineNo">455</span><a name="line.455"></a>
-<span class="sourceLineNo">456</span>  /**<a name="line.456"></a>
-<span class="sourceLineNo">457</span>   * Retrieves and lazily initializes a field storing the locality of every region/server<a name="line.457"></a>
-<span class="sourceLineNo">458</span>   * combination<a name="line.458"></a>
-<span class="sourceLineNo">459</span>   */<a name="line.459"></a>
-<span class="sourceLineNo">460</span>  public float[][] getOrComputeRackLocalities() {<a name="line.460"></a>
-<span class="sourceLineNo">461</span>    if (rackLocalities == null || regionsToMostLocalEntities == null) {<a name="line.461"></a>
-<span class="sourceLineNo">462</span>      computeCachedLocalities();<a name="line.462"></a>
-<span class="sourceLineNo">463</span>    }<a name="line.463"></a>
-<span class="sourceLineNo">464</span>    return rackLocalities;<a name="line.464"></a>
-<span class="sourceLineNo">465</span>  }<a name="line.465"></a>
-<span class="sourceLineNo">466</span><a name="line.466"></a>
-<span class="sourceLineNo">467</span>  /**<a name="line.467"></a>
-<span class="sourceLineNo">468</span>   * Lazily initializes and retrieves a mapping of region -&gt; server for which region has the highest<a name="line.468"></a>
-<span class="sourceLineNo">469</span>   * the locality<a name="line.469"></a>
+<span class="sourceLineNo">450</span>  public float[][] getOrComputeRackLocalities() {<a name="line.450"></a>
+<span class="sourceLineNo">451</span>    if (rackLocalities == null || regionsToMostLocalEntities == null) {<a name="line.451"></a>
+<span class="sourceLineNo">452</span>      computeCachedLocalities();<a name="line.452"></a>
+<span class="sourceLineNo">453</span>    }<a name="line.453"></a>
+<span class="sourceLineNo">454</span>    return rackLocalities;<a name="line.454"></a>
+<span class="sourceLineNo">455</span>  }<a name="line.455"></a>
+<span class="sourceLineNo">456</span><a name="line.456"></a>
+<span class="sourceLineNo">457</span>  /**<a name="line.457"></a>
+<span class="sourceLineNo">458</span>   * Lazily initializes and retrieves a mapping of region -&gt; server for which region has the highest<a name="line.458"></a>
+<span class="sourceLineNo">459</span>   * the locality<a name="line.459"></a>
+<span class="sourceLineNo">460</span>   */<a name="line.460"></a>
+<span class="sourceLineNo">461</span>  public int[] getOrComputeRegionsToMostLocalEntities(BalancerClusterState.LocalityType type) {<a name="line.461"></a>
+<span class="sourceLineNo">462</span>    if (rackLocalities == null || regionsToMostLocalEntities == null) {<a name="line.462"></a>
+<span class="sourceLineNo">463</span>      computeCachedLocalities();<a name="line.463"></a>
+<span class="sourceLineNo">464</span>    }<a name="line.464"></a>
+<span class="sourceLineNo">465</span>    return regionsToMostLocalEntities[type.ordinal()];<a name="line.465"></a>
+<span class="sourceLineNo">466</span>  }<a name="line.466"></a>
+<span class="sourceLineNo">467</span><a name="line.467"></a>
+<span class="sourceLineNo">468</span>  /**<a name="line.468"></a>
+<span class="sourceLineNo">469</span>   * Looks up locality from cache of localities. Will create cache if it does not already exist.<a name="line.469"></a>
 <span class="sourceLineNo">470</span>   */<a name="line.470"></a>
-<span class="sourceLineNo">471</span>  public int[] getOrComputeRegionsToMostLocalEntities(BalancerClusterState.LocalityType type) {<a name="line.471"></a>
-<span class="sourceLineNo">472</span>    if (rackLocalities == null || regionsToMostLocalEntities == null) {<a name="line.472"></a>
-<span class="sourceLineNo">473</span>      computeCachedLocalities();<a name="line.473"></a>
-<span class="sourceLineNo">474</span>    }<a name="line.474"></a>
-<span class="sourceLineNo">475</span>    return regionsToMostLocalEntities[type.ordinal()];<a name="line.475"></a>
-<span class="sourceLineNo">476</span>  }<a name="line.476"></a>
-<span class="sourceLineNo">477</span><a name="line.477"></a>
-<span class="sourceLineNo">478</span>  /**<a name="line.478"></a>
-<span class="sourceLineNo">479</span>   * Looks up locality from cache of localities. Will create cache if it does not already exist.<a name="line.479"></a>
-<span class="sourceLineNo">480</span>   */<a name="line.480"></a>
-<span class="sourceLineNo">481</span>  public float getOrComputeLocality(int region, int entity,<a name="line.481"></a>
-<span class="sourceLineNo">482</span>    BalancerClusterState.LocalityType type) {<a name="line.482"></a>
-<span class="sourceLineNo">483</span>    switch (type) {<a name="line.483"></a>
-<span class="sourceLineNo">484</span>      case SERVER:<a name="line.484"></a>
-<span class="sourceLineNo">485</span>        return getLocalityOfRegion(region, entity);<a name="line.485"></a>
-<span class="sourceLineNo">486</span>      case RACK:<a name="line.486"></a>
-<span class="sourceLineNo">487</span>        return getOrComputeRackLocalities()[region][entity];<a name="line.487"></a>
-<span class="sourceLineNo">488</span>      default:<a name="line.488"></a>
-<span class="sourceLineNo">489</span>        throw new IllegalArgumentException("Unsupported LocalityType: " + type);<a name="line.489"></a>
-<span class="sourceLineNo">490</span>    }<a name="line.490"></a>
-<span class="sourceLineNo">491</span>  }<a name="line.491"></a>
-<span class="sourceLineNo">492</span><a name="line.492"></a>
-<span class="sourceLineNo">493</span>  /**<a name="line.493"></a>
-<span class="sourceLineNo">494</span>   * Returns locality weighted by region size in MB. Will create locality cache if it does not<a name="line.494"></a>
-<span class="sourceLineNo">495</span>   * already exist.<a name="line.495"></a>
-<span class="sourceLineNo">496</span>   */<a name="line.496"></a>
-<span class="sourceLineNo">497</span>  public double getOrComputeWeightedLocality(int region, int server,<a name="line.497"></a>
-<span class="sourceLineNo">498</span>    BalancerClusterState.LocalityType type) {<a name="line.498"></a>
-<span class="sourceLineNo">499</span>    return getRegionSizeMB(region) * getOrComputeLocality(region, server, type);<a name="line.499"></a>
-<span class="sourceLineNo">500</span>  }<a name="line.500"></a>
-<span class="sourceLineNo">501</span><a name="line.501"></a>
-<span class="sourceLineNo">502</span>  /**<a name="line.502"></a>
-<span class="sourceLineNo">503</span>   * Returns the size in MB from the most recent RegionLoad for region<a name="line.503"></a>
-<span class="sourceLineNo">504</span>   */<a name="line.504"></a>
-<span class="sourceLineNo">505</span>  public int getRegionSizeMB(int region) {<a name="line.505"></a>
-<span class="sourceLineNo">506</span>    Deque&lt;BalancerRegionLoad&gt; load = regionLoads[region];<a name="line.506"></a>
-<span class="sourceLineNo">507</span>    // This means regions have no actual data on disk<a name="line.507"></a>
-<span class="sourceLineNo">508</span>    if (load == null) {<a name="line.508"></a>
-<span class="sourceLineNo">509</span>      return 0;<a name="line.509"></a>
-<span class="sourceLineNo">510</span>    }<a name="line.510"></a>
-<span class="sourceLineNo">511</span>    return regionLoads[region].getLast().getStorefileSizeMB();<a name="line.511"></a>
-<span class="sourceLineNo">512</span>  }<a name="line.512"></a>
-<span class="sourceLineNo">513</span><a name="line.513"></a>
-<span class="sourceLineNo">514</span>  /**<a name="line.514"></a>
-<span class="sourceLineNo">515</span>   * Computes and caches the locality for each region/rack combinations, as well as storing a<a name="line.515"></a>
-<span class="sourceLineNo">516</span>   * mapping of region -&gt; server and region -&gt; rack such that server and rack have the highest<a name="line.516"></a>
-<span class="sourceLineNo">517</span>   * locality for region<a name="line.517"></a>
-<span class="sourceLineNo">518</span>   */<a name="line.518"></a>
-<span class="sourceLineNo">519</span>  private void computeCachedLocalities() {<a name="line.519"></a>
-<span class="sourceLineNo">520</span>    rackLocalities = new float[numRegions][numRacks];<a name="line.520"></a>
-<span class="sourceLineNo">521</span>    regionsToMostLocalEntities = new int[LocalityType.values().length][numRegions];<a name="line.521"></a>
-<span class="sourceLineNo">522</span><a name="line.522"></a>
-<span class="sourceLineNo">523</span>    // Compute localities and find most local server per region<a name="line.523"></a>
-<span class="sourceLineNo">524</span>    for (int region = 0; region &lt; numRegions; region++) {<a name="line.524"></a>
-<span class="sourceLineNo">525</span>      int serverWithBestLocality = 0;<a name="line.525"></a>
-<span class="sourceLineNo">526</span>      float bestLocalityForRegion = 0;<a name="line.526"></a>
-<span class="sourceLineNo">527</span>      for (int server = 0; server &lt; numServers; server++) {<a name="line.527"></a>
-<span class="sourceLineNo">528</span>        // Aggregate per-rack locality<a name="line.528"></a>
-<span class="sourceLineNo">529</span>        float locality = getLocalityOfRegion(region, server);<a name="line.529"></a>
-<span class="sourceLineNo">530</span>        int rack = serverIndexToRackIndex[server];<a name="line.530"></a>
-<span class="sourceLineNo">531</span>        int numServersInRack = serversPerRack[rack].length;<a name="line.531"></a>
-<span class="sourceLineNo">532</span>        rackLocalities[region][rack] += locality / numServersInRack;<a name="line.532"></a>
-<span class="sourceLineNo">533</span><a name="line.533"></a>
-<span class="sourceLineNo">534</span>        if (locality &gt; bestLocalityForRegion) {<a name="line.534"></a>
-<span class="sourceLineNo">535</span>          serverWithBestLocality = server;<a name="line.535"></a>
-<span class="sourceLineNo">536</span>          bestLocalityForRegion = locality;<a name="line.536"></a>
-<span class="sourceLineNo">537</span>        }<a name="line.537"></a>
-<span class="sourceLineNo">538</span>      }<a name="line.538"></a>
-<span class="sourceLineNo">539</span>      regionsToMostLocalEntities[LocalityType.SERVER.ordinal()][region] = serverWithBestLocality;<a name="line.539"></a>
-<span class="sourceLineNo">540</span><a name="line.540"></a>
-<span class="sourceLineNo">541</span>      // Find most local rack per region<a name="line.541"></a>
-<span class="sourceLineNo">542</span>      int rackWithBestLocality = 0;<a name="line.542"></a>
-<span class="sourceLineNo">543</span>      float bestRackLocalityForRegion = 0.0f;<a name="line.543"></a>
-<span class="sourceLineNo">544</span>      for (int rack = 0; rack &lt; numRacks; rack++) {<a name="line.544"></a>
-<span class="sourceLineNo">545</span>        float rackLocality = rackLocalities[region][rack];<a name="line.545"></a>
-<span class="sourceLineNo">546</span>        if (rackLocality &gt; bestRackLocalityForRegion) {<a name="line.546"></a>
-<span class="sourceLineNo">547</span>          bestRackLocalityForRegion = rackLocality;<a name="line.547"></a>
-<span class="sourceLineNo">548</span>          rackWithBestLocality = rack;<a name="line.548"></a>
-<span class="sourceLineNo">549</span>        }<a name="line.549"></a>
-<span class="sourceLineNo">550</span>      }<a name="line.550"></a>
-<span class="sourceLineNo">551</span>      regionsToMostLocalEntities[LocalityType.RACK.ordinal()][region] = rackWithBestLocality;<a name="line.551"></a>
-<span class="sourceLineNo">552</span>    }<a name="line.552"></a>
-<span class="sourceLineNo">553</span><a name="line.553"></a>
-<span class="sourceLineNo">554</span>  }<a name="line.554"></a>
-<span class="sourceLineNo">555</span><a name="line.555"></a>
-<span class="sourceLineNo">556</span>  /**<a name="line.556"></a>
-<span class="sourceLineNo">557</span>   * Maps region index to rack index<a name="line.557"></a>
-<span class="sourceLineNo">558</span>   */<a name="line.558"></a>
-<span class="sourceLineNo">559</span>  public int getRackForRegion(int region) {<a name="line.559"></a>
-<span class="sourceLineNo">560</span>    return serverIndexToRackIndex[regionIndexToServerIndex[region]];<a name="line.560"></a>
-<span class="sourceLineNo">561</span>  }<a name="line.561"></a>
-<span class="sourceLineNo">562</span><a name="line.562"></a>
-<span class="sourceLineNo">563</span>  enum LocalityType {<a name="line.563"></a>
-<span class="sourceLineNo">564</span>    SERVER, RACK<a name="line.564"></a>
-<span class="sourceLineNo">565</span>  }<a name="line.565"></a>
-<span class="sourceLineNo">566</span><a name="line.566"></a>
-<span class="sourceLineNo">567</span>  public void doAction(BalanceAction action) {<a name="line.567"></a>
-<span class="sourceLineNo">568</span>    switch (action.getType()) {<a name="line.568"></a>
-<span class="sourceLineNo">569</span>      case NULL:<a name="line.569"></a>
-<span class="sourceLineNo">570</span>        break;<a name="line.570"></a>
-<span class="sourceLineNo">571</span>      case ASSIGN_REGION:<a name="line.571"></a>
-<span class="sourceLineNo">572</span>        // FindBugs: Having the assert quietens FB BC_UNCONFIRMED_CAST warnings<a name="line.572"></a>
-<span class="sourceLineNo">573</span>        assert action instanceof AssignRegionAction : action.getClass();<a name="line.573"></a>
-<span class="sourceLineNo">574</span>        AssignRegionAction ar = (AssignRegionAction) action;<a name="line.574"></a>
-<span class="sourceLineNo">575</span>        regionsPerServer[ar.getServer()] =<a name="line.575"></a>
-<span class="sourceLineNo">576</span>          addRegion(regionsPerServer[ar.getServer()], ar.getRegion());<a name="line.576"></a>
-<span class="sourceLineNo">577</span>        regionMoved(ar.getRegion(), -1, ar.getServer());<a name="line.577"></a>
-<span class="sourceLineNo">578</span>        break;<a name="line.578"></a>
-<span class="sourceLineNo">579</span>      case MOVE_REGION:<a name="line.579"></a>
-<span class="sourceLineNo">580</span>        assert action instanceof MoveRegionAction : action.getClass();<a name="line.580"></a>
-<span class="sourceLineNo">581</span>        MoveRegionAction mra = (MoveRegionAction) action;<a name="line.581"></a>
-<span class="sourceLineNo">582</span>        regionsPerServer[mra.getFromServer()] =<a name="line.582"></a>
-<span class="sourceLineNo">583</span>          removeRegion(regionsPerServer[mra.getFromServer()], mra.getRegion());<a name="line.583"></a>
-<span class="sourceLineNo">584</span>        regionsPerServer[mra.getToServer()] =<a name="line.584"></a>
-<span class="sourceLineNo">585</span>          addRegion(regionsPerServer[mra.getToServer()], mra.getRegion());<a name="line.585"></a>
-<span class="sourceLineNo">586</span>        regionMoved(mra.getRegion(), mra.getFromServer(), mra.getToServer());<a name="line.586"></a>
+<span class="sourceLineNo">471</span>  public float getOrComputeLocality(int region, int entity,<a name="line.471"></a>
+<span class="sourceLineNo">472</span>    BalancerClusterState.LocalityType type) {<a name="line.472"></a>
+<span class="sourceLineNo">473</span>    switch (type) {<a name="line.473"></a>
+<span class="sourceLineNo">474</span>      case SERVER:<a name="line.474"></a>
+<span class="sourceLineNo">475</span>        return getLocalityOfRegion(region, entity);<a name="line.475"></a>
+<span class="sourceLineNo">476</span>      case RACK:<a name="line.476"></a>
+<span class="sourceLineNo">477</span>        return getOrComputeRackLocalities()[region][entity];<a name="line.477"></a>
+<span class="sourceLineNo">478</span>      default:<a name="line.478"></a>
+<span class="sourceLineNo">479</span>        throw new IllegalArgumentException("Unsupported LocalityType: " + type);<a name="line.479"></a>
+<span class="sourceLineNo">480</span>    }<a name="line.480"></a>
+<span class="sourceLineNo">481</span>  }<a name="line.481"></a>
+<span class="sourceLineNo">482</span><a name="line.482"></a>
+<span class="sourceLineNo">483</span>  /**<a name="line.483"></a>
+<span class="sourceLineNo">484</span>   * Returns locality weighted by region size in MB. Will create locality cache if it does not<a name="line.484"></a>
+<span class="sourceLineNo">485</span>   * already exist.<a name="line.485"></a>
+<span class="sourceLineNo">486</span>   */<a name="line.486"></a>
+<span class="sourceLineNo">487</span>  public double getOrComputeWeightedLocality(int region, int server,<a name="line.487"></a>
+<span class="sourceLineNo">488</span>    BalancerClusterState.LocalityType type) {<a name="line.488"></a>
+<span class="sourceLineNo">489</span>    return getRegionSizeMB(region) * getOrComputeLocality(region, server, type);<a name="line.489"></a>
+<span class="sourceLineNo">490</span>  }<a name="line.490"></a>
+<span class="sourceLineNo">491</span><a name="line.491"></a>
+<span class="sourceLineNo">492</span>  /**<a name="line.492"></a>
+<span class="sourceLineNo">493</span>   * Returns the size in MB from the most recent RegionLoad for region<a name="line.493"></a>
+<span class="sourceLineNo">494</span>   */<a name="line.494"></a>
+<span class="sourceLineNo">495</span>  public int getRegionSizeMB(int region) {<a name="line.495"></a>
+<span class="sourceLineNo">496</span>    Deque&lt;BalancerRegionLoad&gt; load = regionLoads[region];<a name="line.496"></a>
+<span class="sourceLineNo">497</span>    // This means regions have no actual data on disk<a name="line.497"></a>
+<span class="sourceLineNo">498</span>    if (load == null) {<a name="line.498"></a>
+<span class="sourceLineNo">499</span>      return 0;<a name="line.499"></a>
+<span class="sourceLineNo">500</span>    }<a name="line.500"></a>
+<span class="sourceLineNo">501</span>    return regionLoads[region].getLast().getStorefileSizeMB();<a name="line.501"></a>
+<span class="sourceLineNo">502</span>  }<a name="line.502"></a>
+<span class="sourceLineNo">503</span><a name="line.503"></a>
+<span class="sourceLineNo">504</span>  /**<a name="line.504"></a>
+<span class="sourceLineNo">505</span>   * Computes and caches the locality for each region/rack combinations, as well as storing a<a name="line.505"></a>
+<span class="sourceLineNo">506</span>   * mapping of region -&gt; server and region -&gt; rack such that server and rack have the highest<a name="line.506"></a>
+<span class="sourceLineNo">507</span>   * locality for region<a name="line.507"></a>
+<span class="sourceLineNo">508</span>   */<a name="line.508"></a>
+<span class="sourceLineNo">509</span>  private void computeCachedLocalities() {<a name="line.509"></a>
+<span class="sourceLineNo">510</span>    rackLocalities = new float[numRegions][numRacks];<a name="line.510"></a>
+<span class="sourceLineNo">511</span>    regionsToMostLocalEntities = new int[LocalityType.values().length][numRegions];<a name="line.511"></a>
+<span class="sourceLineNo">512</span><a name="line.512"></a>
+<span class="sourceLineNo">513</span>    // Compute localities and find most local server per region<a name="line.513"></a>
+<span class="sourceLineNo">514</span>    for (int region = 0; region &lt; numRegions; region++) {<a name="line.514"></a>
+<span class="sourceLineNo">515</span>      int serverWithBestLocality = 0;<a name="line.515"></a>
+<span class="sourceLineNo">516</span>      float bestLocalityForRegion = 0;<a name="line.516"></a>
+<span class="sourceLineNo">517</span>      for (int server = 0; server &lt; numServers; server++) {<a name="line.517"></a>
+<span class="sourceLineNo">518</span>        // Aggregate per-rack locality<a name="line.518"></a>
+<span class="sourceLineNo">519</span>        float locality = getLocalityOfRegion(region, server);<a name="line.519"></a>
+<span class="sourceLineNo">520</span>        int rack = serverIndexToRackIndex[server];<a name="line.520"></a>
+<span class="sourceLineNo">521</span>        int numServersInRack = serversPerRack[rack].length;<a name="line.521"></a>
+<span class="sourceLineNo">522</span>        rackLocalities[region][rack] += locality / numServersInRack;<a name="line.522"></a>
+<span class="sourceLineNo">523</span><a name="line.523"></a>
+<span class="sourceLineNo">524</span>        if (locality &gt; bestLocalityForRegion) {<a name="line.524"></a>
+<span class="sourceLineNo">525</span>          serverWithBestLocality = server;<a name="line.525"></a>
+<span class="sourceLineNo">526</span>          bestLocalityForRegion = locality;<a name="line.526"></a>
+<span class="sourceLineNo">527</span>        }<a name="line.527"></a>
+<span class="sourceLineNo">528</span>      }<a name="line.528"></a>
+<span class="sourceLineNo">529</span>      regionsToMostLocalEntities[LocalityType.SERVER.ordinal()][region] = serverWithBestLocality;<a name="line.529"></a>
+<span class="sourceLineNo">530</span><a name="line.530"></a>
+<span class="sourceLineNo">531</span>      // Find most local rack per region<a name="line.531"></a>
+<span class="sourceLineNo">532</span>      int rackWithBestLocality = 0;<a name="line.532"></a>
+<span class="sourceLineNo">533</span>      float bestRackLocalityForRegion = 0.0f;<a name="line.533"></a>
+<span class="sourceLineNo">534</span>      for (int rack = 0; rack &lt; numRacks; rack++) {<a name="line.534"></a>
+<span class="sourceLineNo">535</span>        float rackLocality = rackLocalities[region][rack];<a name="line.535"></a>
+<span class="sourceLineNo">536</span>        if (rackLocality &gt; bestRackLocalityForRegion) {<a name="line.536"></a>
+<span class="sourceLineNo">537</span>          bestRackLocalityForRegion = rackLocality;<a name="line.537"></a>
+<span class="sourceLineNo">538</span>          rackWithBestLocality = rack;<a name="line.538"></a>
+<span class="sourceLineNo">539</span>        }<a name="line.539"></a>
+<span class="sourceLineNo">540</span>      }<a name="line.540"></a>
+<span class="sourceLineNo">541</span>      regionsToMostLocalEntities[LocalityType.RACK.ordinal()][region] = rackWithBestLocality;<a name="line.541"></a>
+<span class="sourceLineNo">542</span>    }<a name="line.542"></a>
+<span class="sourceLineNo">543</span><a name="line.543"></a>
+<span class="sourceLineNo">544</span>  }<a name="line.544"></a>
+<span class="sourceLineNo">545</span><a name="line.545"></a>
+<span class="sourceLineNo">546</span>  /**<a name="line.546"></a>
+<span class="sourceLineNo">547</span>   * Maps region index to rack index<a name="line.547"></a>
+<span class="sourceLineNo">548</span>   */<a name="line.548"></a>
+<span class="sourceLineNo">549</span>  public int getRackForRegion(int region) {<a name="line.549"></a>
+<span class="sourceLineNo">550</span>    return serverIndexToRackIndex[regionIndexToServerIndex[region]];<a name="line.550"></a>
+<span class="sourceLineNo">551</span>  }<a name="line.551"></a>
+<span class="sourceLineNo">552</span><a name="line.552"></a>
+<span class="sourceLineNo">553</span>  enum LocalityType {<a name="line.553"></a>
+<span class="sourceLineNo">554</span>    SERVER, RACK<a name="line.554"></a>
+<span class="sourceLineNo">555</span>  }<a name="line.555"></a>
+<span class="sourceLineNo">556</span><a name="line.556"></a>
+<span class="sourceLineNo">557</span>  public void doAction(BalanceAction action) {<a name="line.557"></a>
+<span class="sourceLineNo">558</span>    switch (action.getType()) {<a name="line.558"></a>
+<span class="sourceLineNo">559</span>      case NULL:<a name="line.559"></a>
+<span class="sourceLineNo">560</span>        break;<a name="line.560"></a>
+<span class="sourceLineNo">561</span>      case ASSIGN_REGION:<a name="line.561"></a>
+<span class="sourceLineNo">562</span>        // FindBugs: Having the assert quietens FB BC_UNCONFIRMED_CAST warnings<a name="line.562"></a>
+<span class="sourceLineNo">563</span>        assert action instanceof AssignRegionAction : action.getClass();<a name="line.563"></a>
+<span class="sourceLineNo">564</span>        AssignRegionAction ar = (AssignRegionAction) action;<a name="line.564"></a>
+<span class="sourceLineNo">565</span>        regionsPerServer[ar.getServer()] =<a name="line.565"></a>
+<span class="sourceLineNo">566</span>          addRegion(regionsPerServer[ar.getServer()], ar.getRegion());<a name="line.566"></a>
+<span class="sourceLineNo">567</span>        regionMoved(ar.getRegion(), -1, ar.getServer());<a name="line.567"></a>
+<span class="sourceLineNo">568</span>        break;<a name="line.568"></a>
+<span class="sourceLineNo">569</span>      case MOVE_REGION:<a name="line.569"></a>
+<span class="sourceLineNo">570</span>        assert action instanceof MoveRegionAction : action.getClass();<a name="line.570"></a>
+<span class="sourceLineNo">571</span>        MoveRegionAction mra = (MoveRegionAction) action;<a name="line.571"></a>
+<span class="sourceLineNo">572</span>        regionsPerServer[mra.getFromServer()] =<a name="line.572"></a>
+<span class="sourceLineNo">573</span>          removeRegion(regionsPerServer[mra.getFromServer()], mra.getRegion());<a name="line.573"></a>
+<span class="sourceLineNo">574</span>        regionsPerServer[mra.getToServer()] =<a name="line.574"></a>
+<span class="sourceLineNo">575</span>          addRegion(regionsPerServer[mra.getToServer()], mra.getRegion());<a name="line.575"></a>
+<span class="sourceLineNo">576</span>        regionMoved(mra.getRegion(), mra.getFromServer(), mra.getToServer());<a name="line.576"></a>
+<span class="sourceLineNo">577</span>        break;<a name="line.577"></a>
+<span class="sourceLineNo">578</span>      case SWAP_REGIONS:<a name="line.578"></a>
+<span class="sourceLineNo">579</span>        assert action instanceof SwapRegionsAction : action.getClass();<a name="line.579"></a>
+<span class="sourceLineNo">580</span>        SwapRegionsAction a = (SwapRegionsAction) action;<a name="line.580"></a>
+<span class="sourceLineNo">581</span>        regionsPerServer[a.getFromServer()] =<a name="line.581"></a>
+<span class="sourceLineNo">582</span>          replaceRegion(regionsPerServer[a.getFromServer()], a.getFromRegion(), a.getToRegion());<a name="line.582"></a>
+<span class="sourceLineNo">583</span>        regionsPerServer[a.getToServer()] =<a name="line.583"></a>
+<span class="sourceLineNo">584</span>          replaceRegion(regionsPerServer[a.getToServer()], a.getToRegion(), a.getFromRegion());<a name="line.584"></a>
+<span class="sourceLineNo">585</span>        regionMoved(a.getFromRegion(), a.getFromServer(), a.getToServer());<a name="line.585"></a>
+<span class="sourceLineNo">586</span>        regionMoved(a.getToRegion(), a.getToServer(), a.getFromServer());<a name="line.586"></a>
 <span class="sourceLineNo">587</span>        break;<a name="line.587"></a>
-<span class="sourceLineNo">588</span>      case SWAP_REGIONS:<a name="line.588"></a>
-<span class="sourceLineNo">589</span>        assert action instanceof SwapRegionsAction : action.getClass();<a name="line.589"></a>
-<span class="sourceLineNo">590</span>        SwapRegionsAction a = (SwapRegionsAction) action;<a name="line.590"></a>
-<span class="sourceLineNo">591</span>        regionsPerServer[a.getFromServer()] =<a name="line.591"></a>
-<span class="sourceLineNo">592</span>          replaceRegion(regionsPerServer[a.getFromServer()], a.getFromRegion(), a.getToRegion());<a name="line.592"></a>
-<span class="sourceLineNo">593</span>        regionsPerServer[a.getToServer()] =<a name="line.593"></a>
-<span class="sourceLineNo">594</span>          replaceRegion(regionsPerServer[a.getToServer()], a.getToRegion(), a.getFromRegion());<a name="line.594"></a>
-<span class="sourceLineNo">595</span>        regionMoved(a.getFromRegion(), a.getFromServer(), a.getToServer());<a name="line.595"></a>
-<span class="sourceLineNo">596</span>        regionMoved(a.getToRegion(), a.getToServer(), a.getFromServer());<a name="line.596"></a>
-<span class="sourceLineNo">597</span>        break;<a name="line.597"></a>
-<span class="sourceLineNo">598</span>      default:<a name="line.598"></a>
-<span class="sourceLineNo">599</span>        throw new RuntimeException("Uknown action:" + action.getType());<a name="line.599"></a>
-<span class="sourceLineNo">600</span>    }<a name="line.600"></a>
-<span class="sourceLineNo">601</span>  }<a name="line.601"></a>
-<span class="sourceLineNo">602</span><a name="line.602"></a>
-<span class="sourceLineNo">603</span>  /**<a name="line.603"></a>
-<span class="sourceLineNo">604</span>   * Return true if the placement of region on server would lower the availability of the region in<a name="line.604"></a>
-<span class="sourceLineNo">605</span>   * question<a name="line.605"></a>
-<span class="sourceLineNo">606</span>   * @return true or false<a name="line.606"></a>
-<span class="sourceLineNo">607</span>   */<a name="line.607"></a>
-<span class="sourceLineNo">608</span>  boolean wouldLowerAvailability(RegionInfo regionInfo, ServerName serverName) {<a name="line.608"></a>
-<span class="sourceLineNo">609</span>    if (!serversToIndex.containsKey(serverName.getAddress())) {<a name="line.609"></a>
-<span class="sourceLineNo">610</span>      return false; // safeguard against race between cluster.servers and servers from LB method<a name="line.610"></a>
-<span class="sourceLineNo">611</span>                    // args<a name="line.611"></a>
+<span class="sourceLineNo">588</span>      default:<a name="line.588"></a>
+<span class="sourceLineNo">589</span>        throw new RuntimeException("Uknown action:" + action.getType());<a name="line.589"></a>
+<span class="sourceLineNo">590</span>    }<a name="line.590"></a>
+<span class="sourceLineNo">591</span>  }<a name="line.591"></a>
+<span class="sourceLineNo">592</span><a name="line.592"></a>
+<span class="sourceLineNo">593</span>  /**<a name="line.593"></a>
+<span class="sourceLineNo">594</span>   * Return true if the placement of region on server would lower the availability of the region in<a name="line.594"></a>
+<span class="sourceLineNo">595</span>   * question<a name="line.595"></a>
+<span class="sourceLineNo">596</span>   * @return true or false<a name="line.596"></a>
+<span class="sourceLineNo">597</span>   */<a name="line.597"></a>
+<span class="sourceLineNo">598</span>  boolean wouldLowerAvailability(RegionInfo regionInfo, ServerName serverName) {<a name="line.598"></a>
+<span class="sourceLineNo">599</span>    if (!serversToIndex.containsKey(serverName.getAddress())) {<a name="line.599"></a>
+<span class="sourceLineNo">600</span>      return false; // safeguard against race between cluster.servers and servers from LB method<a name="line.600"></a>
+<span class="sourceLineNo">601</span>      // args<a name="line.601"></a>
+<span class="sourceLineNo">602</span>    }<a name="line.602"></a>
+<span class="sourceLineNo">603</span>    int server = serversToIndex.get(serverName.getAddress());<a name="line.603"></a>
+<span class="sourceLineNo">604</span>    int region = regionsToIndex.get(regionInfo);<a name="line.604"></a>
+<span class="sourceLineNo">605</span><a name="line.605"></a>
+<span class="sourceLineNo">606</span>    // Region replicas for same region should better assign to different servers<a name="line.606"></a>
+<span class="sourceLineNo">607</span>    for (int i : regionsPerServer[server]) {<a name="line.607"></a>
+<span class="sourceLineNo">608</span>      RegionInfo otherRegionInfo = regions[i];<a name="line.608"></a>
+<span class="sourceLineNo">609</span>      if (RegionReplicaUtil.isReplicasForSameRegion(regionInfo, otherRegionInfo)) {<a name="line.609"></a>
+<span class="sourceLineNo">610</span>        return true;<a name="line.610"></a>
+<span class="sourceLineNo">611</span>      }<a name="line.611"></a>
 <span class="sourceLineNo">612</span>    }<a name="line.612"></a>
-<span class="sourceLineNo">613</span>    int server = serversToIndex.get(serverName.getAddress());<a name="line.613"></a>
-<span class="sourceLineNo">614</span>    int region = regionsToIndex.get(regionInfo);<a name="line.614"></a>
-<span class="sourceLineNo">615</span><a name="line.615"></a>
-<span class="sourceLineNo">616</span>    // Region replicas for same region should better assign to different servers<a name="line.616"></a>
-<span class="sourceLineNo">617</span>    for (int i : regionsPerServer[server]) {<a name="line.617"></a>
-<span class="sourceLineNo">618</span>      RegionInfo otherRegionInfo = regions[i];<a name="line.618"></a>
-<span class="sourceLineNo">619</span>      if (RegionReplicaUtil.isReplicasForSameRegion(regionInfo, otherRegionInfo)) {<a name="line.619"></a>
-<span class="sourceLineNo">620</span>        return true;<a name="line.620"></a>
-<span class="sourceLineNo">621</span>      }<a name="line.621"></a>
-<span class="sourceLineNo">622</span>    }<a name="line.622"></a>
-<span class="sourceLineNo">623</span><a name="line.623"></a>
-<span class="sourceLineNo">624</span>    int primary = regionIndexToPrimaryIndex[region];<a name="line.624"></a>
-<span class="sourceLineNo">625</span>    if (primary == -1) {<a name="line.625"></a>
-<span class="sourceLineNo">626</span>      return false;<a name="line.626"></a>
-<span class="sourceLineNo">627</span>    }<a name="line.627"></a>
-<span class="sourceLineNo">628</span>    // there is a subset relation for server &lt; host &lt; rack<a name="line.628"></a>
-<span class="sourceLineNo">629</span>    // check server first<a name="line.629"></a>
-<span class="sourceLineNo">630</span>    if (contains(primariesOfRegionsPerServer[server], primary)) {<a name="line.630"></a>
-<span class="sourceLineNo">631</span>      // check for whether there are other servers that we can place this region<a name="line.631"></a>
-<span class="sourceLineNo">632</span>      for (int i = 0; i &lt; primariesOfRegionsPerServer.length; i++) {<a name="line.632"></a>
-<span class="sourceLineNo">633</span>        if (i != server &amp;&amp; !contains(primariesOfRegionsPerServer[i], primary)) {<a name="line.633"></a>
-<span class="sourceLineNo">634</span>          return true; // meaning there is a better server<a name="line.634"></a>
-<span class="sourceLineNo">635</span>        }<a name="line.635"></a>
-<span class="sourceLineNo">636</span>      }<a name="line.636"></a>
-<span class="sourceLineNo">637</span>      return false; // there is not a better server to place this<a name="line.637"></a>
-<span class="sourceLineNo">638</span>    }<a name="line.638"></a>
-<span class="sourceLineNo">639</span><a name="line.639"></a>
-<span class="sourceLineNo">640</span>    // check host<a name="line.640"></a>
-<span class="sourceLineNo">641</span>    if (multiServersPerHost) {<a name="line.641"></a>
-<span class="sourceLineNo">642</span>      // these arrays would only be allocated if we have more than one server per host<a name="line.642"></a>
-<span class="sourceLineNo">643</span>      int host = serverIndexToHostIndex[server];<a name="line.643"></a>
-<span class="sourceLineNo">644</span>      if (contains(primariesOfRegionsPerHost[host], primary)) {<a name="line.644"></a>
-<span class="sourceLineNo">645</span>        // check for whether there are other hosts that we can place this region<a name="line.645"></a>
-<span class="sourceLineNo">646</span>        for (int i = 0; i &lt; primariesOfRegionsPerHost.length; i++) {<a name="line.646"></a>
-<span class="sourceLineNo">647</span>          if (i != host &amp;&amp; !contains(primariesOfRegionsPerHost[i], primary)) {<a name="line.647"></a>
-<span class="sourceLineNo">648</span>            return true; // meaning there is a better host<a name="line.648"></a>
-<span class="sourceLineNo">649</span>          }<a name="line.649"></a>
-<span class="sourceLineNo">650</span>        }<a name="line.650"></a>
-<span class="sourceLineNo">651</span>        return false; // there is not a better host to place this<a name="line.651"></a>
-<span class="sourceLineNo">652</span>      }<a name="line.652"></a>
-<span class="sourceLineNo">653</span>    }<a name="line.653"></a>
-<span class="sourceLineNo">654</span><a name="line.654"></a>
-<span class="sourceLineNo">655</span>    // check rack<a name="line.655"></a>
-<span class="sourceLineNo">656</span>    if (numRacks &gt; 1) {<a name="line.656"></a>
-<span class="sourceLineNo">657</span>      int rack = serverIndexToRackIndex[server];<a name="line.657"></a>
-<span class="sourceLineNo">658</span>      if (contains(primariesOfRegionsPerRack[rack], primary)) {<a name="line.658"></a>
-<span class="sourceLineNo">659</span>        // check for whether there are other racks that we can place this region<a name="line.659"></a>
-<span class="sourceLineNo">660</span>        for (int i = 0; i &lt; primariesOfRegionsPerRack.length; i++) {<a name="line.660"></a>
-<span class="sourceLineNo">661</span>          if (i != rack &amp;&amp; !contains(primariesOfRegionsPerRack[i], primary)) {<a name="line.661"></a>
-<span class="sourceLineNo">662</span>            return true; // meaning there is a better rack<a name="line.662"></a>
-<span class="sourceLineNo">663</span>          }<a name="line.663"></a>
-<span class="sourceLineNo">664</span>        }<a name="line.664"></a>
-<span class="sourceLineNo">665</span>        return false; // there is not a better rack to place this<a name="line.665"></a>
-<span class="sourceLineNo">666</span>      }<a name="line.666"></a>
-<span class="sourceLineNo">667</span>    }<a name="line.667"></a>
-<span class="sourceLineNo">668</span><a name="line.668"></a>
-<span class="sourceLineNo">669</span>    return false;<a name="line.669"></a>
-<span class="sourceLineNo">670</span>  }<a name="line.670"></a>
-<span class="sourceLineNo">671</span><a name="line.671"></a>
-<span class="sourceLineNo">672</span>  void doAssignRegion(RegionInfo regionInfo, ServerName serverName) {<a name="line.672"></a>
-<span class="sourceLineNo">673</span>    if (!serversToIndex.containsKey(serverName.getAddress())) {<a name="line.673"></a>
-<span class="sourceLineNo">674</span>      return;<a name="line.674"></a>
-<span class="sourceLineNo">675</span>    }<a name="line.675"></a>
-<span class="sourceLineNo">676</span>    int server = serversToIndex.get(serverName.getAddress());<a name="line.676"></a>
-<span class="sourceLineNo">677</span>    int region = regionsToIndex.get(regionInfo);<a name="line.677"></a>
-<span class="sourceLineNo">678</span>    doAction(new AssignRegionAction(region, server));<a name="line.678"></a>
-<span class="sourceLineNo">679</span>  }<a name="line.679"></a>
-<span class="sourceLineNo">680</span><a name="line.680"></a>
-<span class="sourceLineNo">681</span>  void regionMoved(int region, int oldServer, int newServer) {<a name="line.681"></a>
-<span class="sourceLineNo">682</span>    regionIndexToServerIndex[region] = newServer;<a name="line.682"></a>
-<span class="sourceLineNo">683</span>    if (initialRegionIndexToServerIndex[region] == newServer) {<a name="line.683"></a>
-<span class="sourceLineNo">684</span>      numMovedRegions--; // region moved back to original location<a name="line.684"></a>
-<span class="sourceLineNo">685</span>    } else if (oldServer &gt;= 0 &amp;&amp; initialRegionIndexToServerIndex[region] == oldServer) {<a name="line.685"></a>
-<span class="sourceLineNo">686</span>      numMovedRegions++; // region moved from original location<a name="line.686"></a>
-<span class="sourceLineNo">687</span>    }<a name="line.687"></a>
-<span class="sourceLineNo">688</span>    int tableIndex = regionIndexToTableIndex[region];<a name="line.688"></a>
-<span class="sourceLineNo">689</span>    if (oldServer &gt;= 0) {<a name="line.689"></a>
-<span class="sourceLineNo">690</span>      numRegionsPerServerPerTable[oldServer][tableIndex]--;<a name="line.690"></a>
-<span class="sourceLineNo">691</span>      // update regionSkewPerTable for the move from old server<a name="line.691"></a>
-<span class="sourceLineNo">692</span>      regionSkewByTable[tableIndex] += getSkewChangeFor(oldServer, tableIndex, -1);<a name="line.692"></a>
-<span class="sourceLineNo">693</span>    }<a name="line.693"></a>
-<span class="sourceLineNo">694</span>    numRegionsPerServerPerTable[newServer][tableIndex]++;<a name="line.694"></a>
-<span class="sourceLineNo">695</span><a name="line.695"></a>
-<span class="sourceLineNo">696</span>    // update regionSkewPerTable for the move to new server<a name="line.696"></a>
-<span class="sourceLineNo">697</span>    regionSkewByTable[tableIndex] += getSkewChangeFor(newServer, tableIndex, 1);<a name="line.697"></a>
+<span class="sourceLineNo">613</span><a name="line.613"></a>
+<span class="sourceLineNo">614</span>    int primary = regionIndexToPrimaryIndex[region];<a name="line.614"></a>
+<span class="sourceLineNo">615</span>    if (primary == -1) {<a name="line.615"></a>
+<span class="sourceLineNo">616</span>      return false;<a name="line.616"></a>
+<span class="sourceLineNo">617</span>    }<a name="line.617"></a>
+<span class="sourceLineNo">618</span>    // there is a subset relation for server &lt; host &lt; rack<a name="line.618"></a>
+<span class="sourceLineNo">619</span>    // check server first<a name="line.619"></a>
+<span class="sourceLineNo">620</span>    int result = checkLocationForPrimary(server, colocatedReplicaCountsPerServer, primary);<a name="line.620"></a>
+<span class="sourceLineNo">621</span>    if (result != 0) {<a name="line.621"></a>
+<span class="sourceLineNo">622</span>      return result &gt; 0;<a name="line.622"></a>
+<span class="sourceLineNo">623</span>    }<a name="line.623"></a>
+<span class="sourceLineNo">624</span><a name="line.624"></a>
+<span class="sourceLineNo">625</span>    // check host<a name="line.625"></a>
+<span class="sourceLineNo">626</span>    if (multiServersPerHost) {<a name="line.626"></a>
+<span class="sourceLineNo">627</span>      result = checkLocationForPrimary(serverIndexToHostIndex[server],<a name="line.627"></a>
+<span class="sourceLineNo">628</span>        colocatedReplicaCountsPerHost, primary);<a name="line.628"></a>
+<span class="sourceLineNo">629</span>      if (result != 0) {<a name="line.629"></a>
+<span class="sourceLineNo">630</span>        return result &gt; 0;<a name="line.630"></a>
+<span class="sourceLineNo">631</span>      }<a name="line.631"></a>
+<span class="sourceLineNo">632</span>    }<a name="line.632"></a>
+<span class="sourceLineNo">633</span><a name="line.633"></a>
+<span class="sourceLineNo">634</span>    // check rack<a name="line.634"></a>
+<span class="sourceLineNo">635</span>    if (numRacks &gt; 1) {<a name="line.635"></a>
+<span class="sourceLineNo">636</span>      result = checkLocationForPrimary(serverIndexToRackIndex[server],<a name="line.636"></a>
+<span class="sourceLineNo">637</span>        colocatedReplicaCountsPerRack, primary);<a name="line.637"></a>
+<span class="sourceLineNo">638</span>      if (result != 0) {<a name="line.638"></a>
+<span class="sourceLineNo">639</span>        return result &gt; 0;<a name="line.639"></a>
+<span class="sourceLineNo">640</span>      }<a name="line.640"></a>
+<span class="sourceLineNo">641</span>    }<a name="line.641"></a>
+<span class="sourceLineNo">642</span>    return false;<a name="line.642"></a>
+<span class="sourceLineNo">643</span>  }<a name="line.643"></a>
+<span class="sourceLineNo">644</span><a name="line.644"></a>
+<span class="sourceLineNo">645</span>  /**<a name="line.645"></a>
+<span class="sourceLineNo">646</span>   * Common method for better solution check.<a name="line.646"></a>
+<span class="sourceLineNo">647</span>   * @param colocatedReplicaCountsPerLocation colocatedReplicaCountsPerHost or<a name="line.647"></a>
+<span class="sourceLineNo">648</span>   *                                          colocatedReplicaCountsPerRack<a name="line.648"></a>
+<span class="sourceLineNo">649</span>   * @return 1 for better, -1 for no better, 0 for unknown<a name="line.649"></a>
+<span class="sourceLineNo">650</span>   */<a name="line.650"></a>
+<span class="sourceLineNo">651</span>  private int checkLocationForPrimary(int location,<a name="line.651"></a>
+<span class="sourceLineNo">652</span>    Int2IntCounterMap[] colocatedReplicaCountsPerLocation, int primary) {<a name="line.652"></a>
+<span class="sourceLineNo">653</span>    if (colocatedReplicaCountsPerLocation[location].containsKey(primary)) {<a name="line.653"></a>
+<span class="sourceLineNo">654</span>      // check for whether there are other Locations that we can place this region<a name="line.654"></a>
+<span class="sourceLineNo">655</span>      for (int i = 0; i &lt; colocatedReplicaCountsPerLocation.length; i++) {<a name="line.655"></a>
+<span class="sourceLineNo">656</span>        if (i != location &amp;&amp; !colocatedReplicaCountsPerLocation[i].containsKey(primary)) {<a name="line.656"></a>
+<span class="sourceLineNo">657</span>          return 1; // meaning there is a better Location<a name="line.657"></a>
+<span class="sourceLineNo">658</span>        }<a name="line.658"></a>
+<span class="sourceLineNo">659</span>      }<a name="line.659"></a>
+<span class="sourceLineNo">660</span>      return -1; // there is not a better Location to place this<a name="line.660"></a>
+<span class="sourceLineNo">661</span>    }<a name="line.661"></a>
+<span class="sourceLineNo">662</span>    return 0;<a name="line.662"></a>
+<span class="sourceLineNo">663</span>  }<a name="line.663"></a>
+<span class="sourceLineNo">664</span><a name="line.664"></a>
+<span class="sourceLineNo">665</span>  void doAssignRegion(RegionInfo regionInfo, ServerName serverName) {<a name="line.665"></a>
+<span class="sourceLineNo">666</span>    if (!serversToIndex.containsKey(serverName.getAddress())) {<a name="line.666"></a>
+<span class="sourceLineNo">667</span>      return;<a name="line.667"></a>
+<span class="sourceLineNo">668</span>    }<a name="line.668"></a>
+<span class="sourceLineNo">669</span>    int server = serversToIndex.get(serverName.getAddress());<a name="line.669"></a>
+<span class="sourceLineNo">670</span>    int region = regionsToIndex.get(regionInfo);<a name="line.670"></a>
+<span class="sourceLineNo">671</span>    doAction(new AssignRegionAction(region, server));<a name="line.671"></a>
+<span class="sourceLineNo">672</span>  }<a name="line.672"></a>
+<span class="sourceLineNo">673</span><a name="line.673"></a>
+<span class="sourceLineNo">674</span>  void regionMoved(int region, int oldServer, int newServer) {<a name="line.674"></a>
+<span class="sourceLineNo">675</span>    regionIndexToServerIndex[region] = newServer;<a name="line.675"></a>
+<span class="sourceLineNo">676</span>    if (initialRegionIndexToServerIndex[region] == newServer) {<a name="line.676"></a>
+<span class="sourceLineNo">677</span>      numMovedRegions--; // region moved back to original location<a name="line.677"></a>
+<span class="sourceLineNo">678</span>    } else if (oldServer &gt;= 0 &amp;&amp; initialRegionIndexToServerIndex[region] == oldServer) {<a name="line.678"></a>
+<span class="sourceLineNo">679</span>      numMovedRegions++; // region moved from original location<a name="line.679"></a>
+<span class="sourceLineNo">680</span>    }<a name="line.680"></a>
+<span class="sourceLineNo">681</span>    int tableIndex = regionIndexToTableIndex[region];<a name="line.681"></a>
+<span class="sourceLineNo">682</span>    if (oldServer &gt;= 0) {<a name="line.682"></a>
+<span class="sourceLineNo">683</span>      numRegionsPerServerPerTable[oldServer][tableIndex]--;<a name="line.683"></a>
+<span class="sourceLineNo">684</span>      // update regionSkewPerTable for the move from old server<a name="line.684"></a>
+<span class="sourceLineNo">685</span>      regionSkewByTable[tableIndex] += getSkewChangeFor(oldServer, tableIndex, -1);<a name="line.685"></a>
+<span class="sourceLineNo">686</span>    }<a name="line.686"></a>
+<span class="sourceLineNo">687</span>    numRegionsPerServerPerTable[newServer][tableIndex]++;<a name="line.687"></a>
+<span class="sourceLineNo">688</span><a name="line.688"></a>
+<span class="sourceLineNo">689</span>    // update regionSkewPerTable for the move to new server<a name="line.689"></a>
+<span class="sourceLineNo">690</span>    regionSkewByTable[tableIndex] += getSkewChangeFor(newServer, tableIndex, 1);<a name="line.690"></a>
+<span class="sourceLineNo">691</span><a name="line.691"></a>
+<span class="sourceLineNo">692</span>    // update for servers<a name="line.692"></a>
+<span class="sourceLineNo">693</span>    int primary = regionIndexToPrimaryIndex[region];<a name="line.693"></a>
+<span class="sourceLineNo">694</span>    if (oldServer &gt;= 0) {<a name="line.694"></a>
+<span class="sourceLineNo">695</span>      colocatedReplicaCountsPerServer[oldServer].getAndDecrement(primary);<a name="line.695"></a>
+<span class="sourceLineNo">696</span>    }<a name="line.696"></a>
+<span class="sourceLineNo">697</span>    colocatedReplicaCountsPerServer[newServer].getAndIncrement(primary);<a name="line.697"></a>
 <span class="sourceLineNo">698</span><a name="line.698"></a>
-<span class="sourceLineNo">699</span>    // update for servers<a name="line.699"></a>
-<span class="sourceLineNo">700</span>    int primary = regionIndexToPrimaryIndex[region];<a name="line.700"></a>
-<span class="sourceLineNo">701</span>    if (oldServer &gt;= 0) {<a name="line.701"></a>
-<span class="sourceLineNo">702</span>      primariesOfRegionsPerServer[oldServer] =<a name="line.702"></a>
-<span class="sourceLineNo">703</span>        removeRegion(primariesOfRegionsPerServer[oldServer], primary);<a name="line.703"></a>
-<span class="sourceLineNo">704</span>    }<a name="line.704"></a>
-<span class="sourceLineNo">705</span>    primariesOfRegionsPerServer[newServer] =<a name="line.705"></a>
-<span class="sourceLineNo">706</span>      addRegionSorted(primariesOfRegionsPerServer[newServer], primary);<a name="line.706"></a>
-<span class="sourceLineNo">707</span><a name="line.707"></a>
-<span class="sourceLineNo">708</span>    // update for hosts<a name="line.708"></a>
-<span class="sourceLineNo">709</span>    if (multiServersPerHost) {<a name="line.709"></a>
-<span class="sourceLineNo">710</span>      int oldHost = oldServer &gt;= 0 ? serverIndexToHostIndex[oldServer] : -1;<a name="line.710"></a>
-<span class="sourceLineNo">711</span>      int newHost = serverIndexToHostIndex[newServer];<a name="line.711"></a>
-<span class="sourceLineNo">712</span>      if (newHost != oldHost) {<a name="line.712"></a>
-<span class="sourceLineNo">713</span>        regionsPerHost[newHost] = addRegion(regionsPerHost[newHost], region);<a name="line.713"></a>
-<span class="sourceLineNo">714</span>        primariesOfRegionsPerHost[newHost] =<a name="line.714"></a>
-<span class="sourceLineNo">715</span>          addRegionSorted(primariesOfRegionsPerHost[newHost], primary);<a name="line.715"></a>
-<span class="sourceLineNo">716</span>        if (oldHost &gt;= 0) {<a name="line.716"></a>
-<span class="sourceLineNo">717</span>          regionsPerHost[oldHost] = removeRegion(regionsPerHost[oldHost], region);<a name="line.717"></a>
-<span class="sourceLineNo">718</span>          primariesOfRegionsPerHost[oldHost] =<a name="line.718"></a>
-<span class="sourceLineNo">719</span>            removeRegion(primariesOfRegionsPerHost[oldHost], primary); // will still be sorted<a name="line.719"></a>
-<span class="sourceLineNo">720</span>        }<a name="line.720"></a>
-<span class="sourceLineNo">721</span>      }<a name="line.721"></a>
-<span class="sourceLineNo">722</span>    }<a name="line.722"></a>
-<span class="sourceLineNo">723</span><a name="line.723"></a>
-<span class="sourceLineNo">724</span>    // update for racks<a name="line.724"></a>
-<span class="sourceLineNo">725</span>    if (numRacks &gt; 1) {<a name="line.725"></a>
-<span class="sourceLineNo">726</span>      int oldRack = oldServer &gt;= 0 ? serverIndexToRackIndex[oldServer] : -1;<a name="line.726"></a>
-<span class="sourceLineNo">727</span>      int newRack = serverIndexToRackIndex[newServer];<a name="line.727"></a>
-<span class="sourceLineNo">728</span>      if (newRack != oldRack) {<a name="line.728"></a>
-<span class="sourceLineNo">729</span>        regionsPerRack[newRack] = addRegion(regionsPerRack[newRack], region);<a name="line.729"></a>
-<span class="sourceLineNo">730</span>        primariesOfRegionsPerRack[newRack] =<a name="line.730"></a>
-<span class="sourceLineNo">731</span>          addRegionSorted(primariesOfRegionsPerRack[newRack], primary);<a name="line.731"></a>
-<span class="sourceLineNo">732</span>        if (oldRack &gt;= 0) {<a name="line.732"></a>
-<span class="sourceLineNo">733</span>          regionsPerRack[oldRack] = removeRegion(regionsPerRack[oldRack], region);<a name="line.733"></a>
-<span class="sourceLineNo">734</span>          primariesOfRegionsPerRack[oldRack] =<a name="line.734"></a>
-<span class="sourceLineNo">735</span>            removeRegion(primariesOfRegionsPerRack[oldRack], primary); // will still be sorted<a name="line.735"></a>
-<span class="sourceLineNo">736</span>        }<a name="line.736"></a>
-<span class="sourceLineNo">737</span>      }<a name="line.737"></a>
-<span class="sourceLineNo">738</span>    }<a name="line.738"></a>
-<span class="sourceLineNo">739</span>  }<a name="line.739"></a>
-<span class="sourceLineNo">740</span><a name="line.740"></a>
-<span class="sourceLineNo">741</span>  int[] removeRegion(int[] regions, int regionIndex) {<a name="line.741"></a>
-<span class="sourceLineNo">742</span>    // TODO: this maybe costly. Consider using linked lists<a name="line.742"></a>
-<span class="sourceLineNo">743</span>    int[] newRegions = new int[regions.length - 1];<a name="line.743"></a>
-<span class="sourceLineNo">744</span>    int i = 0;<a name="line.744"></a>
-<span class="sourceLineNo">745</span>    for (i = 0; i &lt; regions.length; i++) {<a name="line.745"></a>
-<span class="sourceLineNo">746</span>      if (regions[i] == regionIndex) {<a name="line.746"></a>
-<span class="sourceLineNo">747</span>        break;<a name="line.747"></a>
-<span class="sourceLineNo">748</span>      }<a name="line.748"></a>
-<span class="sourceLineNo">749</span>      newRegions[i] = regions[i];<a name="line.749"></a>
-<span class="sourceLineNo">750</span>    }<a name="line.750"></a>
-<span class="sourceLineNo">751</span>    System.arraycopy(regions, i + 1, newRegions, i, newRegions.length - i);<a name="line.751"></a>
+<span class="sourceLineNo">699</span>    // update for hosts<a name="line.699"></a>
+<span class="sourceLineNo">700</span>    if (multiServersPerHost) {<a name="line.700"></a>
+<span class="sourceLineNo">701</span>      updateForLocation(serverIndexToHostIndex, regionsPerHost, colocatedReplicaCountsPerHost,<a name="line.701"></a>
+<span class="sourceLineNo">702</span>        oldServer, newServer, primary, region);<a name="line.702"></a>
+<span class="sourceLineNo">703</span>    }<a name="line.703"></a>
+<span class="sourceLineNo">704</span><a name="line.704"></a>
+<span class="sourceLineNo">705</span>    // update for racks<a name="line.705"></a>
+<span class="sourceLineNo">706</span>    if (numRacks &gt; 1) {<a name="line.706"></a>
+<span class="sourceLineNo">707</span>      updateForLocation(serverIndexToRackIndex, regionsPerRack, colocatedReplicaCountsPerRack,<a name="line.707"></a>
+<span class="sourceLineNo">708</span>        oldServer, newServer, primary, region);<a name="line.708"></a>
+<span class="sourceLineNo">709</span>    }<a name="line.709"></a>
+<span class="sourceLineNo">710</span>  }<a name="line.710"></a>
+<span class="sourceLineNo">711</span>  /**<a name="line.711"></a>
+<span class="sourceLineNo">712</span>   * Common method for per host and per Location region index updates when a region is moved.<a name="line.712"></a>
+<span class="sourceLineNo">713</span>   * @param serverIndexToLocation serverIndexToHostIndex or serverIndexToLocationIndex<a name="line.713"></a>
+<span class="sourceLineNo">714</span>   * @param regionsPerLocation regionsPerHost or regionsPerLocation<a name="line.714"></a>
+<span class="sourceLineNo">715</span>   * @param colocatedReplicaCountsPerLocation colocatedReplicaCountsPerHost or<a name="line.715"></a>
+<span class="sourceLineNo">716</span>   *                                          colocatedReplicaCountsPerRack<a name="line.716"></a>
+<span class="sourceLineNo">717</span>   */<a name="line.717"></a>
+<span class="sourceLineNo">718</span>  private void updateForLocation(int[] serverIndexToLocation,<a name="line.718"></a>
+<span class="sourceLineNo">719</span>    int[][] regionsPerLocation,<a name="line.719"></a>
+<span class="sourceLineNo">720</span>    Int2IntCounterMap[] colocatedReplicaCountsPerLocation,<a name="line.720"></a>
+<span class="sourceLineNo">721</span>    int oldServer, int newServer, int primary, int region) {<a name="line.721"></a>
+<span class="sourceLineNo">722</span>    int oldLocation = oldServer &gt;= 0 ? serverIndexToLocation[oldServer] : -1;<a name="line.722"></a>
+<span class="sourceLineNo">723</span>    int newLocation = serverIndexToLocation[newServer];<a name="line.723"></a>
+<span class="sourceLineNo">724</span>    if (newLocation != oldLocation) {<a name="line.724"></a>
+<span class="sourceLineNo">725</span>      regionsPerLocation[newLocation] = addRegion(regionsPerLocation[newLocation], region);<a name="line.725"></a>
+<span class="sourceLineNo">726</span>      colocatedReplicaCountsPerLocation[newLocation].getAndIncrement(primary);<a name="line.726"></a>
+<span class="sourceLineNo">727</span>      if (oldLocation &gt;= 0) {<a name="line.727"></a>
+<span class="sourceLineNo">728</span>        regionsPerLocation[oldLocation] = removeRegion(regionsPerLocation[oldLocation], region);<a name="line.728"></a>
+<span class="sourceLineNo">729</span>        colocatedReplicaCountsPerLocation[oldLocation].getAndDecrement(primary);<a name="line.729"></a>
+<span class="sourceLineNo">730</span>      }<a name="line.730"></a>
+<span class="sourceLineNo">731</span>    }<a name="line.731"></a>
+<span class="sourceLineNo">732</span><a name="line.732"></a>
+<span class="sourceLineNo">733</span>  }<a name="line.733"></a>
+<span class="sourceLineNo">734</span>  int[] removeRegion(int[] regions, int regionIndex) {<a name="line.734"></a>
+<span class="sourceLineNo">735</span>    // TODO: this maybe costly. Consider using linked lists<a name="line.735"></a>
+<span class="sourceLineNo">736</span>    int[] newRegions = new int[regions.length - 1];<a name="line.736"></a>
+<span class="sourceLineNo">737</span>    int i = 0;<a name="line.737"></a>
+<span class="sourceLineNo">738</span>    for (i = 0; i &lt; regions.length; i++) {<a name="line.738"></a>
+<span class="sourceLineNo">739</span>      if (regions[i] == regionIndex) {<a name="line.739"></a>
+<span class="sourceLineNo">740</span>        break;<a name="line.740"></a>
+<span class="sourceLineNo">741</span>      }<a name="line.741"></a>
+<span class="sourceLineNo">742</span>      newRegions[i] = regions[i];<a name="line.742"></a>
+<span class="sourceLineNo">743</span>    }<a name="line.743"></a>
+<span class="sourceLineNo">744</span>    System.arraycopy(regions, i + 1, newRegions, i, newRegions.length - i);<a name="line.744"></a>
+<span class="sourceLineNo">745</span>    return newRegions;<a name="line.745"></a>
+<span class="sourceLineNo">746</span>  }<a name="line.746"></a>
+<span class="sourceLineNo">747</span><a name="line.747"></a>
+<span class="sourceLineNo">748</span>  int[] addRegion(int[] regions, int regionIndex) {<a name="line.748"></a>
+<span class="sourceLineNo">749</span>    int[] newRegions = new int[regions.length + 1];<a name="line.749"></a>
+<span class="sourceLineNo">750</span>    System.arraycopy(regions, 0, newRegions, 0, regions.length);<a name="line.750"></a>
+<span class="sourceLineNo">751</span>    newRegions[newRegions.length - 1] = regionIndex;<a name="line.751"></a>
 <span class="sourceLineNo">752</span>    return newRegions;<a name="line.752"></a>
 <span class="sourceLineNo">753</span>  }<a name="line.753"></a>
 <span class="sourceLineNo">754</span><a name="line.754"></a>
-<span class="sourceLineNo">755</span>  int[] addRegion(int[] regions, int regionIndex) {<a name="line.755"></a>
+<span class="sourceLineNo">755</span>  int[] addRegionSorted(int[] regions, int regionIndex) {<a name="line.755"></a>
 <span class="sourceLineNo">756</span>    int[] newRegions = new int[regions.length + 1];<a name="line.756"></a>
-<span class="sourceLineNo">757</span>    System.arraycopy(regions, 0, newRegions, 0, regions.length);<a name="line.757"></a>
-<span class="sourceLineNo">758</span>    newRegions[newRegions.length - 1] = regionIndex;<a name="line.758"></a>
-<span class="sourceLineNo">759</span>    return newRegions;<a name="line.759"></a>
-<span class="sourceLineNo">760</span>  }<a name="line.760"></a>
-<span class="sourceLineNo">761</span><a name="line.761"></a>
-<span class="sourceLineNo">762</span>  int[] addRegionSorted(int[] regions, int regionIndex) {<a name="line.762"></a>
-<span class="sourceLineNo">763</span>    int[] newRegions = new int[regions.length + 1];<a name="line.763"></a>
-<span class="sourceLineNo">764</span>    int i = 0;<a name="line.764"></a>
-<span class="sourceLineNo">765</span>    for (i = 0; i &lt; regions.length; i++) { // find the index to insert<a name="line.765"></a>
-<span class="sourceLineNo">766</span>      if (regions[i] &gt; regionIndex) {<a name="line.766"></a>
-<span class="sourceLineNo">767</span>        break;<a name="line.767"></a>
-<span class="sourceLineNo">768</span>      }<a name="line.768"></a>
-<span class="sourceLineNo">769</span>    }<a name="line.769"></a>
-<span class="sourceLineNo">770</span>    System.arraycopy(regions, 0, newRegions, 0, i); // copy first half<a name="line.770"></a>
-<span class="sourceLineNo">771</span>    System.arraycopy(regions, i, newRegions, i + 1, regions.length - i); // copy second half<a name="line.771"></a>
-<span class="sourceLineNo">772</span>    newRegions[i] = regionIndex;<a name="line.772"></a>
-<span class="sourceLineNo">773</span><a name="line.773"></a>
-<span class="sourceLineNo">774</span>    return newRegions;<a name="line.774"></a>
-<span class="sourceLineNo">775</span>  }<a name="line.775"></a>
-<span class="sourceLineNo">776</span><a name="line.776"></a>
-<span class="sourceLineNo">777</span>  int[] replaceRegion(int[] regions, int regionIndex, int newRegionIndex) {<a name="line.777"></a>
-<span class="sourceLineNo">778</span>    int i = 0;<a name="line.778"></a>
-<span class="sourceLineNo">779</span>    for (i = 0; i &lt; regions.length; i++) {<a name="line.779"></a>
-<span class="sourceLineNo">780</span>      if (regions[i] == regionIndex) {<a name="line.780"></a>
-<span class="sourceLineNo">781</span>        regions[i] = newRegionIndex;<a name="line.781"></a>
-<span class="sourceLineNo">782</span>        break;<a name="line.782"></a>
-<span class="sourceLineNo">783</span>      }<a name="line.783"></a>
-<span class="sourceLineNo">784</span>    }<a name="line.784"></a>
-<span class="sourceLineNo">785</span>    return regions;<a name="line.785"></a>
-<span class="sourceLineNo">786</span>  }<a name="line.786"></a>
-<span class="sourceLineNo">787</span><a name="line.787"></a>
-<span class="sourceLineNo">788</span>  void sortServersByRegionCount() {<a name="line.788"></a>
-<span class="sourceLineNo">789</span>    Arrays.sort(serverIndicesSortedByRegionCount, numRegionsComparator);<a name="line.789"></a>
-<span class="sourceLineNo">790</span>  }<a name="line.790"></a>
-<span class="sourceLineNo">791</span><a name="line.791"></a>
-<span class="sourceLineNo">792</span>  int getNumRegions(int server) {<a name="line.792"></a>
-<span class="sourceLineNo">793</span>    return regionsPerServer[server].length;<a name="line.793"></a>
-<span class="sourceLineNo">794</span>  }<a name="line.794"></a>
-<span class="sourceLineNo">795</span><a name="line.795"></a>
-<span class="sourceLineNo">796</span>  boolean contains(int[] arr, int val) {<a name="line.796"></a>
-<span class="sourceLineNo">797</span>    return Arrays.binarySearch(arr, val) &gt;= 0;<a name="line.797"></a>
-<span class="sourceLineNo">798</span>  }<a name="line.798"></a>
-<span class="sourceLineNo">799</span><a name="line.799"></a>
-<span class="sourceLineNo">800</span>  private Comparator&lt;Integer&gt; numRegionsComparator = Comparator.comparingInt(this::getNumRegions);<a name="line.800"></a>
-<span class="sourceLineNo">801</span><a name="line.801"></a>
-<span class="sourceLineNo">802</span>  int getLowestLocalityRegionOnServer(int serverIndex) {<a name="line.802"></a>
-<span class="sourceLineNo">803</span>    if (regionFinder != null) {<a name="line.803"></a>
-<span class="sourceLineNo">804</span>      float lowestLocality = 1.0f;<a name="line.804"></a>
-<span class="sourceLineNo">805</span>      int lowestLocalityRegionIndex = -1;<a name="line.805"></a>
-<span class="sourceLineNo">806</span>      if (regionsPerServer[serverIndex].length == 0) {<a name="line.806"></a>
-<span class="sourceLineNo">807</span>        // No regions on that region server<a name="line.807"></a>
-<span class="sourceLineNo">808</span>        return -1;<a name="line.808"></a>
-<span class="sourceLineNo">809</span>      }<a name="line.809"></a>
-<span class="sourceLineNo">810</span>      for (int j = 0; j &lt; regionsPerServer[serverIndex].length; j++) {<a name="line.810"></a>
-<span class="sourceLineNo">811</span>        int regionIndex = regionsPerServer[serverIndex][j];<a name="line.811"></a>
-<span class="sourceLineNo">812</span>        HDFSBlocksDistribution distribution =<a name="line.812"></a>
-<span class="sourceLineNo">813</span>          regionFinder.getBlockDistribution(regions[regionIndex]);<a name="line.813"></a>
-<span class="sourceLineNo">814</span>        float locality = distribution.getBlockLocalityIndex(servers[serverIndex].getHostname());<a name="line.814"></a>
-<span class="sourceLineNo">815</span>        // skip empty region<a name="line.815"></a>
-<span class="sourceLineNo">816</span>        if (distribution.getUniqueBlocksTotalWeight() == 0) {<a name="line.816"></a>
-<span class="sourceLineNo">817</span>          continue;<a name="line.817"></a>
-<span class="sourceLineNo">818</span>        }<a name="line.818"></a>
-<span class="sourceLineNo">819</span>        if (locality &lt; lowestLocality) {<a name="line.819"></a>
-<span class="sourceLineNo">820</span>          lowestLocality = locality;<a name="line.820"></a>
-<span class="sourceLineNo">821</span>          lowestLocalityRegionIndex = j;<a name="line.821"></a>
-<span class="sourceLineNo">822</span>        }<a name="line.822"></a>
-<span class="sourceLineNo">823</span>      }<a name="line.823"></a>
-<span class="sourceLineNo">824</span>      if (lowestLocalityRegionIndex == -1) {<a name="line.824"></a>
-<span class="sourceLineNo">825</span>        return -1;<a name="line.825"></a>
+<span class="sourceLineNo">757</span>    int i = 0;<a name="line.757"></a>
+<span class="sourceLineNo">758</span>    for (i = 0; i &lt; regions.length; i++) { // find the index to insert<a name="line.758"></a>
+<span class="sourceLineNo">759</span>      if (regions[i] &gt; regionIndex) {<a name="line.759"></a>
+<span class="sourceLineNo">760</span>        break;<a name="line.760"></a>
+<span class="sourceLineNo">761</span>      }<a name="line.761"></a>
+<span class="sourceLineNo">762</span>    }<a name="line.762"></a>
+<span class="sourceLineNo">763</span>    System.arraycopy(regions, 0, newRegions, 0, i); // copy first half<a name="line.763"></a>
+<span class="sourceLineNo">764</span>    System.arraycopy(regions, i, newRegions, i + 1, regions.length - i); // copy second half<a name="line.764"></a>
+<span class="sourceLineNo">765</span>    newRegions[i] = regionIndex;<a name="line.765"></a>
+<span class="sourceLineNo">766</span><a name="line.766"></a>
+<span class="sourceLineNo">767</span>    return newRegions;<a name="line.767"></a>
+<span class="sourceLineNo">768</span>  }<a name="line.768"></a>
+<span class="sourceLineNo">769</span><a name="line.769"></a>
+<span class="sourceLineNo">770</span>  int[] replaceRegion(int[] regions, int regionIndex, int newRegionIndex) {<a name="line.770"></a>
+<span class="sourceLineNo">771</span>    int i = 0;<a name="line.771"></a>
+<span class="sourceLineNo">772</span>    for (i = 0; i &lt; regions.length; i++) {<a name="line.772"></a>
+<span class="sourceLineNo">773</span>      if (regions[i] == regionIndex) {<a name="line.773"></a>
+<span class="sourceLineNo">774</span>        regions[i] = newRegionIndex;<a name="line.774"></a>
+<span class="sourceLineNo">775</span>        break;<a name="line.775"></a>
+<span class="sourceLineNo">776</span>      }<a name="line.776"></a>
+<span class="sourceLineNo">777</span>    }<a name="line.777"></a>
+<span class="sourceLineNo">778</span>    return regions;<a name="line.778"></a>
+<span class="sourceLineNo">779</span>  }<a name="line.779"></a>
+<span class="sourceLineNo">780</span><a name="line.780"></a>
+<span class="sourceLineNo">781</span>  void sortServersByRegionCount() {<a name="line.781"></a>
+<span class="sourceLineNo">782</span>    Arrays.sort(serverIndicesSortedByRegionCount, numRegionsComparator);<a name="line.782"></a>
+<span class="sourceLineNo">783</span>  }<a name="line.783"></a>
+<span class="sourceLineNo">784</span><a name="line.784"></a>
+<span class="sourceLineNo">785</span>  int getNumRegions(int server) {<a name="line.785"></a>
+<span class="sourceLineNo">786</span>    return regionsPerServer[server].length;<a name="line.786"></a>
+<span class="sourceLineNo">787</span>  }<a name="line.787"></a>
+<span class="sourceLineNo">788</span><a name="line.788"></a>
+<span class="sourceLineNo">789</span>  boolean contains(int[] arr, int val) {<a name="line.789"></a>
+<span class="sourceLineNo">790</span>    return Arrays.binarySearch(arr, val) &gt;= 0;<a name="line.790"></a>
+<span class="sourceLineNo">791</span>  }<a name="line.791"></a>
+<span class="sourceLineNo">792</span><a name="line.792"></a>
+<span class="sourceLineNo">793</span>  private Comparator&lt;Integer&gt; numRegionsComparator = Comparator.comparingInt(this::getNumRegions);<a name="line.793"></a>
+<span class="sourceLineNo">794</span><a name="line.794"></a>
+<span class="sourceLineNo">795</span>  int getLowestLocalityRegionOnServer(int serverIndex) {<a name="line.795"></a>
+<span class="sourceLineNo">796</span>    if (regionFinder != null) {<a name="line.796"></a>
+<span class="sourceLineNo">797</span>      float lowestLocality = 1.0f;<a name="line.797"></a>
+<span class="sourceLineNo">798</span>      int lowestLocalityRegionIndex = -1;<a name="line.798"></a>
+<span class="sourceLineNo">799</span>      if (regionsPerServer[serverIndex].length == 0) {<a name="line.799"></a>
+<span class="sourceLineNo">800</span>        // No regions on that region server<a name="line.800"></a>
+<span class="sourceLineNo">801</span>        return -1;<a name="line.801"></a>
+<span class="sourceLineNo">802</span>      }<a name="line.802"></a>
+<span class="sourceLineNo">803</span>      for (int j = 0; j &lt; regionsPerServer[serverIndex].length; j++) {<a name="line.803"></a>
+<span class="sourceLineNo">804</span>        int regionIndex = regionsPerServer[serverIndex][j];<a name="line.804"></a>
+<span class="sourceLineNo">805</span>        HDFSBlocksDistribution distribution =<a name="line.805"></a>
+<span class="sourceLineNo">806</span>          regionFinder.getBlockDistribution(regions[regionIndex]);<a name="line.806"></a>
+<span class="sourceLineNo">807</span>        float locality = distribution.getBlockLocalityIndex(servers[serverIndex].getHostname());<a name="line.807"></a>
+<span class="sourceLineNo">808</span>        // skip empty region<a name="line.808"></a>
+<span class="sourceLineNo">809</span>        if (distribution.getUniqueBlocksTotalWeight() == 0) {<a name="line.809"></a>
+<span class="sourceLineNo">810</span>          continue;<a name="line.810"></a>
+<span class="sourceLineNo">811</span>        }<a name="line.811"></a>
+<span class="sourceLineNo">812</span>        if (locality &lt; lowestLocality) {<a name="line.812"></a>
+<span class="sourceLineNo">813</span>          lowestLocality = locality;<a name="line.813"></a>
+<span class="sourceLineNo">814</span>          lowestLocalityRegionIndex = j;<a name="line.814"></a>
+<span class="sourceLineNo">815</span>        }<a name="line.815"></a>
+<span class="sourceLineNo">816</span>      }<a name="line.816"></a>
+<span class="sourceLineNo">817</span>      if (lowestLocalityRegionIndex == -1) {<a name="line.817"></a>
+<span class="sourceLineNo">818</span>        return -1;<a name="line.818"></a>
+<span class="sourceLineNo">819</span>      }<a name="line.819"></a>
+<span class="sourceLineNo">820</span>      if (LOG.isTraceEnabled()) {<a name="line.820"></a>
+<span class="sourceLineNo">821</span>        LOG.trace("Lowest locality region is " +<a name="line.821"></a>
+<span class="sourceLineNo">822</span>          regions[regionsPerServer[serverIndex][lowestLocalityRegionIndex]]<a name="line.822"></a>
+<span class="sourceLineNo">823</span>            .getRegionNameAsString() +<a name="line.823"></a>
+<span class="sourceLineNo">824</span>          " with locality " + lowestLocality + " and its region server contains " +<a name="line.824"></a>
+<span class="sourceLineNo">825</span>          regionsPerServer[serverIndex].length + " regions");<a name="line.825"></a>
 <span class="sourceLineNo">826</span>      }<a name="line.826"></a>
-<span class="sourceLineNo">827</span>      if (LOG.isTraceEnabled()) {<a name="line.827"></a>
-<span class="sourceLineNo">828</span>        LOG.trace("Lowest locality region is " +<a name="line.828"></a>
-<span class="sourceLineNo">829</span>          regions[regionsPerServer[serverIndex][lowestLocalityRegionIndex]]<a name="line.829"></a>
-<span class="sourceLineNo">830</span>            .getRegionNameAsString() +<a name="line.830"></a>
-<span class="sourceLineNo">831</span>          " with locality " + lowestLocality + " and its region server contains " +<a name="line.831"></a>
-<span class="sourceLineNo">832</span>          regionsPerServer[serverIndex].length + " regions");<a name="line.832"></a>
-<span class="sourceLineNo">833</span>      }<a name="line.833"></a>
-<span class="sourceLineNo">834</span>      return regionsPerServer[serverIndex][lowestLocalityRegionIndex];<a name="line.834"></a>
-<span class="sourceLineNo">835</span>    } else {<a name="line.835"></a>
-<span class="sourceLineNo">836</span>      return -1;<a name="line.836"></a>
-<span class="sourceLineNo">837</span>    }<a name="line.837"></a>
-<span class="sourceLineNo">838</span>  }<a name="line.838"></a>
-<span class="sourceLineNo">839</span><a name="line.839"></a>
-<span class="sourceLineNo">840</span>  float getLocalityOfRegion(int region, int server) {<a name="line.840"></a>
-<span class="sourceLineNo">841</span>    if (regionFinder != null) {<a name="line.841"></a>
-<span class="sourceLineNo">842</span>      HDFSBlocksDistribution distribution = regionFinder.getBlockDistribution(regions[region]);<a name="line.842"></a>
-<span class="sourceLineNo">843</span>      return distribution.getBlockLocalityIndex(servers[server].getHostname());<a name="line.843"></a>
-<span class="sourceLineNo">844</span>    } else {<a name="line.844"></a>
-<span class="sourceLineNo">845</span>      return 0f;<a name="line.845"></a>
-<span class="sourceLineNo">846</span>    }<a name="line.846"></a>
-<span class="sourceLineNo">847</span>  }<a name="line.847"></a>
-<span class="sourceLineNo">848</span><a name="line.848"></a>
-<span class="sourceLineNo">849</span>  void setNumRegions(int numRegions) {<a name="line.849"></a>
-<span class="sourceLineNo">850</span>    this.numRegions = numRegions;<a name="line.850"></a>
-<span class="sourceLineNo">851</span>  }<a name="line.851"></a>
-<span class="sourceLineNo">852</span><a name="line.852"></a>
-<span class="sourceLineNo">853</span>  void setNumMovedRegions(int numMovedRegions) {<a name="line.853"></a>
-<span class="sourceLineNo">854</span>    this.numMovedRegions = numMovedRegions;<a name="line.854"></a>
-<span class="sourceLineNo">855</span>  }<a name="line.855"></a>
-<span class="sourceLineNo">856</span><a name="line.856"></a>
-<span class="sourceLineNo">857</span>  @Override<a name="line.857"></a>
-<span class="sourceLineNo">858</span>  public String toString() {<a name="line.858"></a>
-<span class="sourceLineNo">859</span>    StringBuilder desc = new StringBuilder("Cluster={servers=[");<a name="line.859"></a>
-<span class="sourceLineNo">860</span>    for (ServerName sn : servers) {<a name="line.860"></a>
-<span class="sourceLineNo">861</span>      desc.append(sn.getAddress().toString()).append(", ");<a name="line.861"></a>
-<span class="sourceLineNo">862</span>    }<a name="line.862"></a>
-<span class="sourceLineNo">863</span>    desc.append("], serverIndicesSortedByRegionCount=")<a name="line.863"></a>
-<span class="sourceLineNo">864</span>      .append(Arrays.toString(serverIndicesSortedByRegionCount)).append(", regionsPerServer=")<a name="line.864"></a>
-<span class="sourceLineNo">865</span>      .append(Arrays.deepToString(regionsPerServer));<a name="line.865"></a>
+<span class="sourceLineNo">827</span>      return regionsPerServer[serverIndex][lowestLocalityRegionIndex];<a name="line.827"></a>
+<span class="sourceLineNo">828</span>    } else {<a name="line.828"></a>
+<span class="sourceLineNo">829</span>      return -1;<a name="line.829"></a>
+<span class="sourceLineNo">830</span>    }<a name="line.830"></a>
+<span class="sourceLineNo">831</span>  }<a name="line.831"></a>
+<span class="sourceLineNo">832</span><a name="line.832"></a>
+<span class="sourceLineNo">833</span>  float getLocalityOfRegion(int region, int server) {<a name="line.833"></a>
+<span class="sourceLineNo">834</span>    if (regionFinder != null) {<a name="line.834"></a>
+<span class="sourceLineNo">835</span>      HDFSBlocksDistribution distribution = regionFinder.getBlockDistribution(regions[region]);<a name="line.835"></a>
+<span class="sourceLineNo">836</span>      return distribution.getBlockLocalityIndex(servers[server].getHostname());<a name="line.836"></a>
+<span class="sourceLineNo">837</span>    } else {<a name="line.837"></a>
+<span class="sourceLineNo">838</span>      return 0f;<a name="line.838"></a>
+<span class="sourceLineNo">839</span>    }<a name="line.839"></a>
+<span class="sourceLineNo">840</span>  }<a name="line.840"></a>
+<span class="sourceLineNo">841</span><a name="line.841"></a>
+<span class="sourceLineNo">842</span>  void setNumRegions(int numRegions) {<a name="line.842"></a>
+<span class="sourceLineNo">843</span>    this.numRegions = numRegions;<a name="line.843"></a>
+<span class="sourceLineNo">844</span>  }<a name="line.844"></a>
+<span class="sourceLineNo">845</span><a name="line.845"></a>
+<span class="sourceLineNo">846</span>  void setNumMovedRegions(int numMovedRegions) {<a name="line.846"></a>
+<span class="sourceLineNo">847</span>    this.numMovedRegions = numMovedRegions;<a name="line.847"></a>
+<span class="sourceLineNo">848</span>  }<a name="line.848"></a>
+<span class="sourceLineNo">849</span><a name="line.849"></a>
+<span class="sourceLineNo">850</span>  @Override<a name="line.850"></a>
+<span class="sourceLineNo">851</span>  public String toString() {<a name="line.851"></a>
+<span class="sourceLineNo">852</span>    StringBuilder desc = new StringBuilder("Cluster={servers=[");<a name="line.852"></a>
+<span class="sourceLineNo">853</span>    for (ServerName sn : servers) {<a name="line.853"></a>
+<span class="sourceLineNo">854</span>      desc.append(sn.getAddress().toString()).append(", ");<a name="line.854"></a>
+<span class="sourceLineNo">855</span>    }<a name="line.855"></a>
+<span class="sourceLineNo">856</span>    desc.append("], serverIndicesSortedByRegionCount=")<a name="line.856"></a>
+<span class="sourceLineNo">857</span>      .append(Arrays.toString(serverIndicesSortedByRegionCount)).append(", regionsPerServer=")<a name="line.857"></a>
+<span class="sourceLineNo">858</span>      .append(Arrays.deepToString(regionsPerServer));<a name="line.858"></a>
+<span class="sourceLineNo">859</span><a name="line.859"></a>
+<span class="sourceLineNo">860</span>    desc.append(", regionSkewByTable=").append(Arrays.toString(regionSkewByTable))<a name="line.860"></a>
+<span class="sourceLineNo">861</span>      .append(", numRegions=").append(numRegions).append(", numServers=").append(numServers)<a name="line.861"></a>
+<span class="sourceLineNo">862</span>      .append(", numTables=").append(numTables).append(", numMovedRegions=").append(numMovedRegions)<a name="line.862"></a>
+<span class="sourceLineNo">863</span>      .append('}');<a name="line.863"></a>
+<span class="sourceLineNo">864</span>    return desc.toString();<a name="line.864"></a>
+<span class="sourceLineNo">865</span>  }<a name="line.865"></a>
 <span class="sourceLineNo">866</span><a name="line.866"></a>
-<span class="sourceLineNo">867</span>    desc.append(", regionSkewByTable=").append(Arrays.toString(regionSkewByTable))<a name="line.867"></a>
-<span class="sourceLineNo">868</span>      .append(", numRegions=").append(numRegions).append(", numServers=").append(numServers)<a name="line.868"></a>
-<span class="sourceLineNo">869</span>      .append(", numTables=").append(numTables).append(", numMovedRegions=").append(numMovedRegions)<a name="line.869"></a>
-<span class="sourceLineNo">870</span>      .append('}');<a name="line.870"></a>
-<span class="sourceLineNo">871</span>    return desc.toString();<a name="line.871"></a>
-<span class="sourceLineNo">872</span>  }<a name="line.872"></a>
-<span class="sourceLineNo">873</span><a name="line.873"></a>
-<span class="sourceLineNo">874</span>  private double getSkewChangeFor(int serverIndex, int tableIndex, int regionCountChange) {<a name="line.874"></a>
-<span class="sourceLineNo">875</span>    double curSkew = Math.abs(numRegionsPerServerPerTable[serverIndex][tableIndex] -<a name="line.875"></a>
-<span class="sourceLineNo">876</span>      meanRegionsPerTable[tableIndex]);<a name="line.876"></a>
-<span class="sourceLineNo">877</span>    double oldSkew = Math.abs(numRegionsPerServerPerTable[serverIndex][tableIndex] -<a name="line.877"></a>
-<span class="sourceLineNo">878</span>      regionCountChange - meanRegionsPerTable[tableIndex]);<a name="line.878"></a>
-<span class="sourceLineNo">879</span>    return curSkew - oldSkew;<a name="line.879"></a>
-<span class="sourceLineNo">880</span>  }<a name="line.880"></a>
-<span class="sourceLineNo">881</span>}<a name="line.881"></a>
+<span class="sourceLineNo">867</span>  private double getSkewChangeFor(int serverIndex, int tableIndex, int regionCountChange) {<a name="line.867"></a>
+<span class="sourceLineNo">868</span>    double curSkew = Math.abs(numRegionsPerServerPerTable[serverIndex][tableIndex] -<a name="line.868"></a>
+<span class="sourceLineNo">869</span>      meanRegionsPerTable[tableIndex]);<a name="line.869"></a>
+<span class="sourceLineNo">870</span>    double oldSkew = Math.abs(numRegionsPerServerPerTable[serverIndex][tableIndex] -<a name="line.870"></a>
+<span class="sourceLineNo">871</span>      regionCountChange - meanRegionsPerTable[tableIndex]);<a name="line.871"></a>
+<span class="sourceLineNo">872</span>    return curSkew - oldSkew;<a name="line.872"></a>
+<span class="sourceLineNo">873</span>  }<a name="line.873"></a>
+<span class="sourceLineNo">874</span>}<a name="line.874"></a>
 
 
 
diff --git a/devapidocs/src-html/org/apache/hadoop/hbase/master/balancer/RegionReplicaCandidateGenerator.html b/devapidocs/src-html/org/apache/hadoop/hbase/master/balancer/RegionReplicaCandidateGenerator.html
index 72f463d..7269114 100644
--- a/devapidocs/src-html/org/apache/hadoop/hbase/master/balancer/RegionReplicaCandidateGenerator.html
+++ b/devapidocs/src-html/org/apache/hadoop/hbase/master/balancer/RegionReplicaCandidateGenerator.html
@@ -27,89 +27,77 @@
 <span class="sourceLineNo">019</span>package org.apache.hadoop.hbase.master.balancer;<a name="line.19"></a>
 <span class="sourceLineNo">020</span><a name="line.20"></a>
 <span class="sourceLineNo">021</span>import java.util.concurrent.ThreadLocalRandom;<a name="line.21"></a>
-<span class="sourceLineNo">022</span>import org.apache.yetus.audience.InterfaceAudience;<a name="line.22"></a>
-<span class="sourceLineNo">023</span><a name="line.23"></a>
-<span class="sourceLineNo">024</span>/**<a name="line.24"></a>
-<span class="sourceLineNo">025</span> * Generates candidates which moves the replicas out of the region server for co-hosted region<a name="line.25"></a>
-<span class="sourceLineNo">026</span> * replicas<a name="line.26"></a>
-<span class="sourceLineNo">027</span> */<a name="line.27"></a>
-<span class="sourceLineNo">028</span>@InterfaceAudience.Private<a name="line.28"></a>
-<span class="sourceLineNo">029</span>class RegionReplicaCandidateGenerator extends CandidateGenerator {<a name="line.29"></a>
-<span class="sourceLineNo">030</span><a name="line.30"></a>
-<span class="sourceLineNo">031</span>  protected final RandomCandidateGenerator randomGenerator = new RandomCandidateGenerator();<a name="line.31"></a>
-<span class="sourceLineNo">032</span><a name="line.32"></a>
-<span class="sourceLineNo">033</span>  /**<a name="line.33"></a>
-<span class="sourceLineNo">034</span>   * Randomly select one regionIndex out of all region replicas co-hosted in the same group (a group<a name="line.34"></a>
-<span class="sourceLineNo">035</span>   * is a server, host or rack)<a name="line.35"></a>
-<span class="sourceLineNo">036</span>   * @param primariesOfRegionsPerGroup either Cluster.primariesOfRegionsPerServer,<a name="line.36"></a>
-<span class="sourceLineNo">037</span>   *          primariesOfRegionsPerHost or primariesOfRegionsPerRack<a name="line.37"></a>
-<span class="sourceLineNo">038</span>   * @param regionsPerGroup either Cluster.regionsPerServer, regionsPerHost or regionsPerRack<a name="line.38"></a>
-<span class="sourceLineNo">039</span>   * @param regionIndexToPrimaryIndex Cluster.regionsIndexToPrimaryIndex<a name="line.39"></a>
-<span class="sourceLineNo">040</span>   * @return a regionIndex for the selected primary or -1 if there is no co-locating<a name="line.40"></a>
-<span class="sourceLineNo">041</span>   */<a name="line.41"></a>
-<span class="sourceLineNo">042</span>  int selectCoHostedRegionPerGroup(int[] primariesOfRegionsPerGroup, int[] regionsPerGroup,<a name="line.42"></a>
-<span class="sourceLineNo">043</span>    int[] regionIndexToPrimaryIndex) {<a name="line.43"></a>
-<span class="sourceLineNo">044</span>    int currentPrimary = -1;<a name="line.44"></a>
-<span class="sourceLineNo">045</span>    int currentPrimaryIndex = -1;<a name="line.45"></a>
-<span class="sourceLineNo">046</span>    int selectedPrimaryIndex = -1;<a name="line.46"></a>
-<span class="sourceLineNo">047</span>    double currentLargestRandom = -1;<a name="line.47"></a>
-<span class="sourceLineNo">048</span>    // primariesOfRegionsPerGroup is a sorted array. Since it contains the primary region<a name="line.48"></a>
-<span class="sourceLineNo">049</span>    // ids for the regions hosted in server, a consecutive repetition means that replicas<a name="line.49"></a>
-<span class="sourceLineNo">050</span>    // are co-hosted<a name="line.50"></a>
-<span class="sourceLineNo">051</span>    for (int j = 0; j &lt;= primariesOfRegionsPerGroup.length; j++) {<a name="line.51"></a>
-<span class="sourceLineNo">052</span>      int primary = j &lt; primariesOfRegionsPerGroup.length ? primariesOfRegionsPerGroup[j] : -1;<a name="line.52"></a>
-<span class="sourceLineNo">053</span>      if (primary != currentPrimary) { // check for whether we see a new primary<a name="line.53"></a>
-<span class="sourceLineNo">054</span>        int numReplicas = j - currentPrimaryIndex;<a name="line.54"></a>
-<span class="sourceLineNo">055</span>        if (numReplicas &gt; 1) { // means consecutive primaries, indicating co-location<a name="line.55"></a>
-<span class="sourceLineNo">056</span>          // decide to select this primary region id or not<a name="line.56"></a>
-<span class="sourceLineNo">057</span>          double currentRandom = ThreadLocalRandom.current().nextDouble();<a name="line.57"></a>
-<span class="sourceLineNo">058</span>          // we don't know how many region replicas are co-hosted, we will randomly select one<a name="line.58"></a>
-<span class="sourceLineNo">059</span>          // using reservoir sampling (http://gregable.com/2007/10/reservoir-sampling.html)<a name="line.59"></a>
-<span class="sourceLineNo">060</span>          if (currentRandom &gt; currentLargestRandom) {<a name="line.60"></a>
-<span class="sourceLineNo">061</span>            selectedPrimaryIndex = currentPrimary;<a name="line.61"></a>
-<span class="sourceLineNo">062</span>            currentLargestRandom = currentRandom;<a name="line.62"></a>
-<span class="sourceLineNo">063</span>          }<a name="line.63"></a>
-<span class="sourceLineNo">064</span>        }<a name="line.64"></a>
-<span class="sourceLineNo">065</span>        currentPrimary = primary;<a name="line.65"></a>
-<span class="sourceLineNo">066</span>        currentPrimaryIndex = j;<a name="line.66"></a>
-<span class="sourceLineNo">067</span>      }<a name="line.67"></a>
-<span class="sourceLineNo">068</span>    }<a name="line.68"></a>
-<span class="sourceLineNo">069</span><a name="line.69"></a>
-<span class="sourceLineNo">070</span>    // we have found the primary id for the region to move. Now find the actual regionIndex<a name="line.70"></a>
-<span class="sourceLineNo">071</span>    // with the given primary, prefer to move the secondary region.<a name="line.71"></a>
-<span class="sourceLineNo">072</span>    for (int regionIndex : regionsPerGroup) {<a name="line.72"></a>
-<span class="sourceLineNo">073</span>      if (selectedPrimaryIndex == regionIndexToPrimaryIndex[regionIndex]) {<a name="line.73"></a>
-<span class="sourceLineNo">074</span>        // always move the secondary, not the primary<a name="line.74"></a>
-<span class="sourceLineNo">075</span>        if (selectedPrimaryIndex != regionIndex) {<a name="line.75"></a>
-<span class="sourceLineNo">076</span>          return regionIndex;<a name="line.76"></a>
-<span class="sourceLineNo">077</span>        }<a name="line.77"></a>
-<span class="sourceLineNo">078</span>      }<a name="line.78"></a>
-<span class="sourceLineNo">079</span>    }<a name="line.79"></a>
-<span class="sourceLineNo">080</span>    return -1;<a name="line.80"></a>
-<span class="sourceLineNo">081</span>  }<a name="line.81"></a>
-<span class="sourceLineNo">082</span><a name="line.82"></a>
-<span class="sourceLineNo">083</span>  @Override<a name="line.83"></a>
-<span class="sourceLineNo">084</span>  BalanceAction generate(BalancerClusterState cluster) {<a name="line.84"></a>
-<span class="sourceLineNo">085</span>    int serverIndex = pickRandomServer(cluster);<a name="line.85"></a>
-<span class="sourceLineNo">086</span>    if (cluster.numServers &lt;= 1 || serverIndex == -1) {<a name="line.86"></a>
-<span class="sourceLineNo">087</span>      return BalanceAction.NULL_ACTION;<a name="line.87"></a>
-<span class="sourceLineNo">088</span>    }<a name="line.88"></a>
-<span class="sourceLineNo">089</span><a name="line.89"></a>
-<span class="sourceLineNo">090</span>    int regionIndex = selectCoHostedRegionPerGroup(cluster.primariesOfRegionsPerServer[serverIndex],<a name="line.90"></a>
-<span class="sourceLineNo">091</span>      cluster.regionsPerServer[serverIndex], cluster.regionIndexToPrimaryIndex);<a name="line.91"></a>
-<span class="sourceLineNo">092</span><a name="line.92"></a>
-<span class="sourceLineNo">093</span>    // if there are no pairs of region replicas co-hosted, default to random generator<a name="line.93"></a>
-<span class="sourceLineNo">094</span>    if (regionIndex == -1) {<a name="line.94"></a>
-<span class="sourceLineNo">095</span>      // default to randompicker<a name="line.95"></a>
-<span class="sourceLineNo">096</span>      return randomGenerator.generate(cluster);<a name="line.96"></a>
-<span class="sourceLineNo">097</span>    }<a name="line.97"></a>
-<span class="sourceLineNo">098</span><a name="line.98"></a>
-<span class="sourceLineNo">099</span>    int toServerIndex = pickOtherRandomServer(cluster, serverIndex);<a name="line.99"></a>
-<span class="sourceLineNo">100</span>    int toRegionIndex = pickRandomRegion(cluster, toServerIndex, 0.9f);<a name="line.100"></a>
-<span class="sourceLineNo">101</span>    return getAction(serverIndex, regionIndex, toServerIndex, toRegionIndex);<a name="line.101"></a>
-<span class="sourceLineNo">102</span>  }<a name="line.102"></a>
-<span class="sourceLineNo">103</span><a name="line.103"></a>
-<span class="sourceLineNo">104</span>}<a name="line.104"></a>
+<span class="sourceLineNo">022</span><a name="line.22"></a>
+<span class="sourceLineNo">023</span>import org.agrona.collections.Int2IntCounterMap;<a name="line.23"></a>
+<span class="sourceLineNo">024</span>import org.agrona.collections.IntArrayList;<a name="line.24"></a>
+<span class="sourceLineNo">025</span>import org.apache.yetus.audience.InterfaceAudience;<a name="line.25"></a>
+<span class="sourceLineNo">026</span><a name="line.26"></a>
+<span class="sourceLineNo">027</span>/**<a name="line.27"></a>
+<span class="sourceLineNo">028</span> * Generates candidates which moves the replicas out of the region server for co-hosted region<a name="line.28"></a>
+<span class="sourceLineNo">029</span> * replicas<a name="line.29"></a>
+<span class="sourceLineNo">030</span> */<a name="line.30"></a>
+<span class="sourceLineNo">031</span>@InterfaceAudience.Private<a name="line.31"></a>
+<span class="sourceLineNo">032</span>class RegionReplicaCandidateGenerator extends CandidateGenerator {<a name="line.32"></a>
+<span class="sourceLineNo">033</span><a name="line.33"></a>
+<span class="sourceLineNo">034</span>  protected final RandomCandidateGenerator randomGenerator = new RandomCandidateGenerator();<a name="line.34"></a>
+<span class="sourceLineNo">035</span><a name="line.35"></a>
+<span class="sourceLineNo">036</span>  /**<a name="line.36"></a>
+<span class="sourceLineNo">037</span>   * Randomly select one regionIndex out of all region replicas co-hosted in the same group (a group<a name="line.37"></a>
+<span class="sourceLineNo">038</span>   * is a server, host or rack)<a name="line.38"></a>
+<span class="sourceLineNo">039</span>   * @param colocatedReplicaCountsPerGroup either Cluster.colocatedReplicaCountsPerServer,<a name="line.39"></a>
+<span class="sourceLineNo">040</span>   *          colocatedReplicaCountsPerHost or colocatedReplicaCountsPerRack<a name="line.40"></a>
+<span class="sourceLineNo">041</span>   * @param regionsPerGroup either Cluster.regionsPerServer, regionsPerHost or regionsPerRack<a name="line.41"></a>
+<span class="sourceLineNo">042</span>   * @param regionIndexToPrimaryIndex Cluster.regionsIndexToPrimaryIndex<a name="line.42"></a>
+<span class="sourceLineNo">043</span>   * @return a regionIndex for the selected primary or -1 if there is no co-locating<a name="line.43"></a>
+<span class="sourceLineNo">044</span>   */<a name="line.44"></a>
+<span class="sourceLineNo">045</span>  int selectCoHostedRegionPerGroup(Int2IntCounterMap colocatedReplicaCountsPerGroup,<a name="line.45"></a>
+<span class="sourceLineNo">046</span>    int[] regionsPerGroup, int[] regionIndexToPrimaryIndex) {<a name="line.46"></a>
+<span class="sourceLineNo">047</span>    final IntArrayList colocated = new IntArrayList(colocatedReplicaCountsPerGroup.size(), -1);<a name="line.47"></a>
+<span class="sourceLineNo">048</span>    colocatedReplicaCountsPerGroup.forEach((primary, count) -&gt; {<a name="line.48"></a>
+<span class="sourceLineNo">049</span>      if (count &gt; 1) { // means consecutive primaries, indicating co-location<a name="line.49"></a>
+<span class="sourceLineNo">050</span>        colocated.add(primary);<a name="line.50"></a>
+<span class="sourceLineNo">051</span>      }<a name="line.51"></a>
+<span class="sourceLineNo">052</span>    });<a name="line.52"></a>
+<span class="sourceLineNo">053</span><a name="line.53"></a>
+<span class="sourceLineNo">054</span>    if (!colocated.isEmpty()) {<a name="line.54"></a>
+<span class="sourceLineNo">055</span>      int rand = ThreadLocalRandom.current().nextInt(colocated.size());<a name="line.55"></a>
+<span class="sourceLineNo">056</span>      int selectedPrimaryIndex = colocated.get(rand);<a name="line.56"></a>
+<span class="sourceLineNo">057</span>      // we have found the primary id for the region to move. Now find the actual regionIndex<a name="line.57"></a>
+<span class="sourceLineNo">058</span>      // with the given primary, prefer to move the secondary region.<a name="line.58"></a>
+<span class="sourceLineNo">059</span>      for (int regionIndex : regionsPerGroup) {<a name="line.59"></a>
+<span class="sourceLineNo">060</span>        if (selectedPrimaryIndex == regionIndexToPrimaryIndex[regionIndex]) {<a name="line.60"></a>
+<span class="sourceLineNo">061</span>          // always move the secondary, not the primary<a name="line.61"></a>
+<span class="sourceLineNo">062</span>          if (selectedPrimaryIndex != regionIndex) {<a name="line.62"></a>
+<span class="sourceLineNo">063</span>            return regionIndex;<a name="line.63"></a>
+<span class="sourceLineNo">064</span>          }<a name="line.64"></a>
+<span class="sourceLineNo">065</span>        }<a name="line.65"></a>
+<span class="sourceLineNo">066</span>      }<a name="line.66"></a>
+<span class="sourceLineNo">067</span>    }<a name="line.67"></a>
+<span class="sourceLineNo">068</span>    return -1;<a name="line.68"></a>
+<span class="sourceLineNo">069</span>  }<a name="line.69"></a>
+<span class="sourceLineNo">070</span><a name="line.70"></a>
+<span class="sourceLineNo">071</span>  @Override<a name="line.71"></a>
+<span class="sourceLineNo">072</span>  BalanceAction generate(BalancerClusterState cluster) {<a name="line.72"></a>
+<span class="sourceLineNo">073</span>    int serverIndex = pickRandomServer(cluster);<a name="line.73"></a>
+<span class="sourceLineNo">074</span>    if (cluster.numServers &lt;= 1 || serverIndex == -1) {<a name="line.74"></a>
+<span class="sourceLineNo">075</span>      return BalanceAction.NULL_ACTION;<a name="line.75"></a>
+<span class="sourceLineNo">076</span>    }<a name="line.76"></a>
+<span class="sourceLineNo">077</span><a name="line.77"></a>
+<span class="sourceLineNo">078</span>    int regionIndex = selectCoHostedRegionPerGroup(<a name="line.78"></a>
+<span class="sourceLineNo">079</span>      cluster.colocatedReplicaCountsPerServer[serverIndex],<a name="line.79"></a>
+<span class="sourceLineNo">080</span>      cluster.regionsPerServer[serverIndex], cluster.regionIndexToPrimaryIndex);<a name="line.80"></a>
+<span class="sourceLineNo">081</span><a name="line.81"></a>
+<span class="sourceLineNo">082</span>    // if there are no pairs of region replicas co-hosted, default to random generator<a name="line.82"></a>
+<span class="sourceLineNo">083</span>    if (regionIndex == -1) {<a name="line.83"></a>
+<span class="sourceLineNo">084</span>      // default to randompicker<a name="line.84"></a>
+<span class="sourceLineNo">085</span>      return randomGenerator.generate(cluster);<a name="line.85"></a>
+<span class="sourceLineNo">086</span>    }<a name="line.86"></a>
+<span class="sourceLineNo">087</span><a name="line.87"></a>
+<span class="sourceLineNo">088</span>    int toServerIndex = pickOtherRandomServer(cluster, serverIndex);<a name="line.88"></a>
+<span class="sourceLineNo">089</span>    int toRegionIndex = pickRandomRegion(cluster, toServerIndex, 0.9f);<a name="line.89"></a>
+<span class="sourceLineNo">090</span>    return getAction(serverIndex, regionIndex, toServerIndex, toRegionIndex);<a name="line.90"></a>
+<span class="sourceLineNo">091</span>  }<a name="line.91"></a>
+<span class="sourceLineNo">092</span>}<a name="line.92"></a>
 
 
 
diff --git a/devapidocs/src-html/org/apache/hadoop/hbase/master/balancer/RegionReplicaGroupingCostFunction.html b/devapidocs/src-html/org/apache/hadoop/hbase/master/balancer/RegionReplicaGroupingCostFunction.html
index 1a1da3a..d31213f 100644
--- a/devapidocs/src-html/org/apache/hadoop/hbase/master/balancer/RegionReplicaGroupingCostFunction.html
+++ b/devapidocs/src-html/org/apache/hadoop/hbase/master/balancer/RegionReplicaGroupingCostFunction.html
@@ -25,91 +25,83 @@
 <span class="sourceLineNo">017</span> */<a name="line.17"></a>
 <span class="sourceLineNo">018</span>package org.apache.hadoop.hbase.master.balancer;<a name="line.18"></a>
 <span class="sourceLineNo">019</span><a name="line.19"></a>
-<span class="sourceLineNo">020</span>import java.util.Arrays;<a name="line.20"></a>
-<span class="sourceLineNo">021</span>import org.apache.yetus.audience.InterfaceAudience;<a name="line.21"></a>
-<span class="sourceLineNo">022</span><a name="line.22"></a>
-<span class="sourceLineNo">023</span>/**<a name="line.23"></a>
-<span class="sourceLineNo">024</span> * A cost function for region replicas. We give a high cost for hosting replicas of the same region<a name="line.24"></a>
-<span class="sourceLineNo">025</span> * in the same server, host or rack. We do not prevent the case though, since if numReplicas &gt;<a name="line.25"></a>
-<span class="sourceLineNo">026</span> * numRegionServers, we still want to keep the replica open.<a name="line.26"></a>
-<span class="sourceLineNo">027</span> */<a name="line.27"></a>
-<span class="sourceLineNo">028</span>@InterfaceAudience.Private<a name="line.28"></a>
-<span class="sourceLineNo">029</span>abstract class RegionReplicaGroupingCostFunction extends CostFunction {<a name="line.29"></a>
-<span class="sourceLineNo">030</span><a name="line.30"></a>
-<span class="sourceLineNo">031</span>  protected long maxCost = 0;<a name="line.31"></a>
-<span class="sourceLineNo">032</span>  protected long[] costsPerGroup; // group is either server, host or rack<a name="line.32"></a>
-<span class="sourceLineNo">033</span><a name="line.33"></a>
-<span class="sourceLineNo">034</span>  @Override<a name="line.34"></a>
-<span class="sourceLineNo">035</span>  final void prepare(BalancerClusterState cluster) {<a name="line.35"></a>
-<span class="sourceLineNo">036</span>    super.prepare(cluster);<a name="line.36"></a>
-<span class="sourceLineNo">037</span>    if (!isNeeded()) {<a name="line.37"></a>
-<span class="sourceLineNo">038</span>      return;<a name="line.38"></a>
-<span class="sourceLineNo">039</span>    }<a name="line.39"></a>
-<span class="sourceLineNo">040</span>    loadCosts();<a name="line.40"></a>
-<span class="sourceLineNo">041</span>  }<a name="line.41"></a>
-<span class="sourceLineNo">042</span><a name="line.42"></a>
-<span class="sourceLineNo">043</span>  protected abstract void loadCosts();<a name="line.43"></a>
-<span class="sourceLineNo">044</span><a name="line.44"></a>
-<span class="sourceLineNo">045</span>  protected final long getMaxCost(BalancerClusterState cluster) {<a name="line.45"></a>
-<span class="sourceLineNo">046</span>    // max cost is the case where every region replica is hosted together regardless of host<a name="line.46"></a>
-<span class="sourceLineNo">047</span>    int[] primariesOfRegions = new int[cluster.numRegions];<a name="line.47"></a>
-<span class="sourceLineNo">048</span>    System.arraycopy(cluster.regionIndexToPrimaryIndex, 0, primariesOfRegions, 0,<a name="line.48"></a>
-<span class="sourceLineNo">049</span>      cluster.regions.length);<a name="line.49"></a>
-<span class="sourceLineNo">050</span><a name="line.50"></a>
-<span class="sourceLineNo">051</span>    Arrays.sort(primariesOfRegions);<a name="line.51"></a>
-<span class="sourceLineNo">052</span><a name="line.52"></a>
-<span class="sourceLineNo">053</span>    // compute numReplicas from the sorted array<a name="line.53"></a>
-<span class="sourceLineNo">054</span>    return costPerGroup(primariesOfRegions);<a name="line.54"></a>
-<span class="sourceLineNo">055</span>  }<a name="line.55"></a>
-<span class="sourceLineNo">056</span><a name="line.56"></a>
-<span class="sourceLineNo">057</span>  @Override<a name="line.57"></a>
-<span class="sourceLineNo">058</span>  boolean isNeeded() {<a name="line.58"></a>
-<span class="sourceLineNo">059</span>    return cluster.hasRegionReplicas;<a name="line.59"></a>
-<span class="sourceLineNo">060</span>  }<a name="line.60"></a>
-<span class="sourceLineNo">061</span><a name="line.61"></a>
-<span class="sourceLineNo">062</span>  @Override<a name="line.62"></a>
-<span class="sourceLineNo">063</span>  protected double cost() {<a name="line.63"></a>
-<span class="sourceLineNo">064</span>    if (maxCost &lt;= 0) {<a name="line.64"></a>
-<span class="sourceLineNo">065</span>      return 0;<a name="line.65"></a>
-<span class="sourceLineNo">066</span>    }<a name="line.66"></a>
-<span class="sourceLineNo">067</span><a name="line.67"></a>
-<span class="sourceLineNo">068</span>    long totalCost = 0;<a name="line.68"></a>
-<span class="sourceLineNo">069</span>    for (int i = 0; i &lt; costsPerGroup.length; i++) {<a name="line.69"></a>
-<span class="sourceLineNo">070</span>      totalCost += costsPerGroup[i];<a name="line.70"></a>
-<span class="sourceLineNo">071</span>    }<a name="line.71"></a>
-<span class="sourceLineNo">072</span>    return scale(0, maxCost, totalCost);<a name="line.72"></a>
-<span class="sourceLineNo">073</span>  }<a name="line.73"></a>
-<span class="sourceLineNo">074</span><a name="line.74"></a>
-<span class="sourceLineNo">075</span>  /**<a name="line.75"></a>
-<span class="sourceLineNo">076</span>   * For each primary region, it computes the total number of replicas in the array (numReplicas)<a name="line.76"></a>
-<span class="sourceLineNo">077</span>   * and returns a sum of numReplicas-1 squared. For example, if the server hosts regions a, b, c,<a name="line.77"></a>
-<span class="sourceLineNo">078</span>   * d, e, f where a and b are same replicas, and c,d,e are same replicas, it returns (2-1) * (2-1)<a name="line.78"></a>
-<span class="sourceLineNo">079</span>   * + (3-1) * (3-1) + (1-1) * (1-1).<a name="line.79"></a>
-<span class="sourceLineNo">080</span>   * @param primariesOfRegions a sorted array of primary regions ids for the regions hosted<a name="line.80"></a>
-<span class="sourceLineNo">081</span>   * @return a sum of numReplicas-1 squared for each primary region in the group.<a name="line.81"></a>
-<span class="sourceLineNo">082</span>   */<a name="line.82"></a>
-<span class="sourceLineNo">083</span>  protected final long costPerGroup(int[] primariesOfRegions) {<a name="line.83"></a>
-<span class="sourceLineNo">084</span>    long cost = 0;<a name="line.84"></a>
-<span class="sourceLineNo">085</span>    int currentPrimary = -1;<a name="line.85"></a>
-<span class="sourceLineNo">086</span>    int currentPrimaryIndex = -1;<a name="line.86"></a>
-<span class="sourceLineNo">087</span>    // primariesOfRegions is a sorted array of primary ids of regions. Replicas of regions<a name="line.87"></a>
+<span class="sourceLineNo">020</span>import java.util.concurrent.atomic.AtomicLong;<a name="line.20"></a>
+<span class="sourceLineNo">021</span><a name="line.21"></a>
+<span class="sourceLineNo">022</span>import org.agrona.collections.Hashing;<a name="line.22"></a>
+<span class="sourceLineNo">023</span>import org.agrona.collections.Int2IntCounterMap;<a name="line.23"></a>
+<span class="sourceLineNo">024</span><a name="line.24"></a>
+<span class="sourceLineNo">025</span>import org.apache.yetus.audience.InterfaceAudience;<a name="line.25"></a>
+<span class="sourceLineNo">026</span><a name="line.26"></a>
+<span class="sourceLineNo">027</span>/**<a name="line.27"></a>
+<span class="sourceLineNo">028</span> * A cost function for region replicas. We give a high cost for hosting replicas of the same region<a name="line.28"></a>
+<span class="sourceLineNo">029</span> * in the same server, host or rack. We do not prevent the case though, since if numReplicas &gt;<a name="line.29"></a>
+<span class="sourceLineNo">030</span> * numRegionServers, we still want to keep the replica open.<a name="line.30"></a>
+<span class="sourceLineNo">031</span> */<a name="line.31"></a>
+<span class="sourceLineNo">032</span>@InterfaceAudience.Private<a name="line.32"></a>
+<span class="sourceLineNo">033</span>abstract class RegionReplicaGroupingCostFunction extends CostFunction {<a name="line.33"></a>
+<span class="sourceLineNo">034</span>  protected long maxCost = 0;<a name="line.34"></a>
+<span class="sourceLineNo">035</span>  protected long[] costsPerGroup; // group is either server, host or rack<a name="line.35"></a>
+<span class="sourceLineNo">036</span><a name="line.36"></a>
+<span class="sourceLineNo">037</span>  @Override<a name="line.37"></a>
+<span class="sourceLineNo">038</span>  final void prepare(BalancerClusterState cluster) {<a name="line.38"></a>
+<span class="sourceLineNo">039</span>    super.prepare(cluster);<a name="line.39"></a>
+<span class="sourceLineNo">040</span>    if (!isNeeded()) {<a name="line.40"></a>
+<span class="sourceLineNo">041</span>      return;<a name="line.41"></a>
+<span class="sourceLineNo">042</span>    }<a name="line.42"></a>
+<span class="sourceLineNo">043</span>    loadCosts();<a name="line.43"></a>
+<span class="sourceLineNo">044</span>  }<a name="line.44"></a>
+<span class="sourceLineNo">045</span><a name="line.45"></a>
+<span class="sourceLineNo">046</span>  protected abstract void loadCosts();<a name="line.46"></a>
+<span class="sourceLineNo">047</span><a name="line.47"></a>
+<span class="sourceLineNo">048</span>  protected final long getMaxCost(BalancerClusterState cluster) {<a name="line.48"></a>
+<span class="sourceLineNo">049</span>    // max cost is the case where every region replica is hosted together regardless of host<a name="line.49"></a>
+<span class="sourceLineNo">050</span>    Int2IntCounterMap colocatedReplicaCounts = new Int2IntCounterMap(cluster.numRegions,<a name="line.50"></a>
+<span class="sourceLineNo">051</span>      Hashing.DEFAULT_LOAD_FACTOR, 0);<a name="line.51"></a>
+<span class="sourceLineNo">052</span>    for (int i = 0; i &lt; cluster.regionIndexToPrimaryIndex.length; i++) {<a name="line.52"></a>
+<span class="sourceLineNo">053</span>      colocatedReplicaCounts.getAndIncrement(cluster.regionIndexToPrimaryIndex[i]);<a name="line.53"></a>
+<span class="sourceLineNo">054</span>    }<a name="line.54"></a>
+<span class="sourceLineNo">055</span>    // compute numReplicas from the sorted array<a name="line.55"></a>
+<span class="sourceLineNo">056</span>    return costPerGroup(colocatedReplicaCounts);<a name="line.56"></a>
+<span class="sourceLineNo">057</span>  }<a name="line.57"></a>
+<span class="sourceLineNo">058</span><a name="line.58"></a>
+<span class="sourceLineNo">059</span>  @Override<a name="line.59"></a>
+<span class="sourceLineNo">060</span>  boolean isNeeded() {<a name="line.60"></a>
+<span class="sourceLineNo">061</span>    return cluster.hasRegionReplicas;<a name="line.61"></a>
+<span class="sourceLineNo">062</span>  }<a name="line.62"></a>
+<span class="sourceLineNo">063</span><a name="line.63"></a>
+<span class="sourceLineNo">064</span>  @Override<a name="line.64"></a>
+<span class="sourceLineNo">065</span>  protected double cost() {<a name="line.65"></a>
+<span class="sourceLineNo">066</span>    if (maxCost &lt;= 0) {<a name="line.66"></a>
+<span class="sourceLineNo">067</span>      return 0;<a name="line.67"></a>
+<span class="sourceLineNo">068</span>    }<a name="line.68"></a>
+<span class="sourceLineNo">069</span><a name="line.69"></a>
+<span class="sourceLineNo">070</span>    long totalCost = 0;<a name="line.70"></a>
+<span class="sourceLineNo">071</span>    for (int i = 0; i &lt; costsPerGroup.length; i++) {<a name="line.71"></a>
+<span class="sourceLineNo">072</span>      totalCost += costsPerGroup[i];<a name="line.72"></a>
+<span class="sourceLineNo">073</span>    }<a name="line.73"></a>
+<span class="sourceLineNo">074</span>    return scale(0, maxCost, totalCost);<a name="line.74"></a>
+<span class="sourceLineNo">075</span>  }<a name="line.75"></a>
+<span class="sourceLineNo">076</span><a name="line.76"></a>
+<span class="sourceLineNo">077</span>  /**<a name="line.77"></a>
+<span class="sourceLineNo">078</span>   * For each primary region, it computes the total number of replicas in the array (numReplicas)<a name="line.78"></a>
+<span class="sourceLineNo">079</span>   * and returns a sum of numReplicas-1 squared. For example, if the server hosts regions a, b, c,<a name="line.79"></a>
+<span class="sourceLineNo">080</span>   * d, e, f where a and b are same replicas, and c,d,e are same replicas, it returns (2-1) * (2-1)<a name="line.80"></a>
+<span class="sourceLineNo">081</span>   * + (3-1) * (3-1) + (1-1) * (1-1).<a name="line.81"></a>
+<span class="sourceLineNo">082</span>   * @param colocatedReplicaCounts a sorted array of primary regions ids for the regions hosted<a name="line.82"></a>
+<span class="sourceLineNo">083</span>   * @return a sum of numReplicas-1 squared for each primary region in the group.<a name="line.83"></a>
+<span class="sourceLineNo">084</span>   */<a name="line.84"></a>
+<span class="sourceLineNo">085</span>  protected final long costPerGroup(Int2IntCounterMap colocatedReplicaCounts) {<a name="line.85"></a>
+<span class="sourceLineNo">086</span>    final AtomicLong cost = new AtomicLong(0);<a name="line.86"></a>
+<span class="sourceLineNo">087</span>    // colocatedReplicaCounts is a sorted array of primary ids of regions. Replicas of regions<a name="line.87"></a>
 <span class="sourceLineNo">088</span>    // sharing the same primary will have consecutive numbers in the array.<a name="line.88"></a>
-<span class="sourceLineNo">089</span>    for (int j = 0; j &lt;= primariesOfRegions.length; j++) {<a name="line.89"></a>
-<span class="sourceLineNo">090</span>      int primary = j &lt; primariesOfRegions.length ? primariesOfRegions[j] : -1;<a name="line.90"></a>
-<span class="sourceLineNo">091</span>      if (primary != currentPrimary) { // we see a new primary<a name="line.91"></a>
-<span class="sourceLineNo">092</span>        int numReplicas = j - currentPrimaryIndex;<a name="line.92"></a>
-<span class="sourceLineNo">093</span>        // square the cost<a name="line.93"></a>
-<span class="sourceLineNo">094</span>        if (numReplicas &gt; 1) { // means consecutive primaries, indicating co-location<a name="line.94"></a>
-<span class="sourceLineNo">095</span>          cost += (numReplicas - 1) * (numReplicas - 1);<a name="line.95"></a>
-<span class="sourceLineNo">096</span>        }<a name="line.96"></a>
-<span class="sourceLineNo">097</span>        currentPrimary = primary;<a name="line.97"></a>
-<span class="sourceLineNo">098</span>        currentPrimaryIndex = j;<a name="line.98"></a>
-<span class="sourceLineNo">099</span>      }<a name="line.99"></a>
-<span class="sourceLineNo">100</span>    }<a name="line.100"></a>
-<span class="sourceLineNo">101</span><a name="line.101"></a>
-<span class="sourceLineNo">102</span>    return cost;<a name="line.102"></a>
-<span class="sourceLineNo">103</span>  }<a name="line.103"></a>
-<span class="sourceLineNo">104</span>}<a name="line.104"></a>
+<span class="sourceLineNo">089</span>    colocatedReplicaCounts.forEach((primary,count) -&gt; {<a name="line.89"></a>
+<span class="sourceLineNo">090</span>      if (count &gt; 1) { // means consecutive primaries, indicating co-location<a name="line.90"></a>
+<span class="sourceLineNo">091</span>        cost.getAndAdd((count - 1) * (count - 1));<a name="line.91"></a>
+<span class="sourceLineNo">092</span>      }<a name="line.92"></a>
+<span class="sourceLineNo">093</span>    });<a name="line.93"></a>
+<span class="sourceLineNo">094</span>    return cost.longValue();<a name="line.94"></a>
+<span class="sourceLineNo">095</span>  }<a name="line.95"></a>
+<span class="sourceLineNo">096</span>}<a name="line.96"></a>
 
 
 
diff --git a/devapidocs/src-html/org/apache/hadoop/hbase/master/balancer/RegionReplicaHostCostFunction.html b/devapidocs/src-html/org/apache/hadoop/hbase/master/balancer/RegionReplicaHostCostFunction.html
index 4c7e285..17fbbf4 100644
--- a/devapidocs/src-html/org/apache/hadoop/hbase/master/balancer/RegionReplicaHostCostFunction.html
+++ b/devapidocs/src-html/org/apache/hadoop/hbase/master/balancer/RegionReplicaHostCostFunction.html
@@ -25,58 +25,60 @@
 <span class="sourceLineNo">017</span> */<a name="line.17"></a>
 <span class="sourceLineNo">018</span>package org.apache.hadoop.hbase.master.balancer;<a name="line.18"></a>
 <span class="sourceLineNo">019</span><a name="line.19"></a>
-<span class="sourceLineNo">020</span>import org.apache.hadoop.conf.Configuration;<a name="line.20"></a>
-<span class="sourceLineNo">021</span>import org.apache.yetus.audience.InterfaceAudience;<a name="line.21"></a>
-<span class="sourceLineNo">022</span><a name="line.22"></a>
-<span class="sourceLineNo">023</span>/**<a name="line.23"></a>
-<span class="sourceLineNo">024</span> * A cost function for region replicas. We give a very high cost to hosting replicas of the same<a name="line.24"></a>
-<span class="sourceLineNo">025</span> * region in the same host. We do not prevent the case though, since if numReplicas &gt;<a name="line.25"></a>
-<span class="sourceLineNo">026</span> * numRegionServers, we still want to keep the replica open.<a name="line.26"></a>
-<span class="sourceLineNo">027</span> */<a name="line.27"></a>
-<span class="sourceLineNo">028</span>@InterfaceAudience.Private<a name="line.28"></a>
-<span class="sourceLineNo">029</span>class RegionReplicaHostCostFunction extends RegionReplicaGroupingCostFunction {<a name="line.29"></a>
-<span class="sourceLineNo">030</span><a name="line.30"></a>
-<span class="sourceLineNo">031</span>  private static final String REGION_REPLICA_HOST_COST_KEY =<a name="line.31"></a>
-<span class="sourceLineNo">032</span>    "hbase.master.balancer.stochastic.regionReplicaHostCostKey";<a name="line.32"></a>
-<span class="sourceLineNo">033</span>  private static final float DEFAULT_REGION_REPLICA_HOST_COST_KEY = 100000;<a name="line.33"></a>
-<span class="sourceLineNo">034</span><a name="line.34"></a>
-<span class="sourceLineNo">035</span>  private int[][] primariesOfRegionsPerGroup;<a name="line.35"></a>
-<span class="sourceLineNo">036</span><a name="line.36"></a>
-<span class="sourceLineNo">037</span>  public RegionReplicaHostCostFunction(Configuration conf) {<a name="line.37"></a>
-<span class="sourceLineNo">038</span>    this.setMultiplier(<a name="line.38"></a>
-<span class="sourceLineNo">039</span>      conf.getFloat(REGION_REPLICA_HOST_COST_KEY, DEFAULT_REGION_REPLICA_HOST_COST_KEY));<a name="line.39"></a>
-<span class="sourceLineNo">040</span>  }<a name="line.40"></a>
-<span class="sourceLineNo">041</span><a name="line.41"></a>
-<span class="sourceLineNo">042</span>  @Override<a name="line.42"></a>
-<span class="sourceLineNo">043</span>  protected void loadCosts() {<a name="line.43"></a>
-<span class="sourceLineNo">044</span>    // max cost is the case where every region replica is hosted together regardless of host<a name="line.44"></a>
-<span class="sourceLineNo">045</span>    maxCost = cluster.numHosts &gt; 1 ? getMaxCost(cluster) : 0;<a name="line.45"></a>
-<span class="sourceLineNo">046</span>    costsPerGroup = new long[cluster.numHosts];<a name="line.46"></a>
-<span class="sourceLineNo">047</span>    primariesOfRegionsPerGroup = cluster.multiServersPerHost // either server based or host based<a name="line.47"></a>
-<span class="sourceLineNo">048</span>      ? cluster.primariesOfRegionsPerHost : cluster.primariesOfRegionsPerServer;<a name="line.48"></a>
-<span class="sourceLineNo">049</span>    for (int i = 0; i &lt; primariesOfRegionsPerGroup.length; i++) {<a name="line.49"></a>
-<span class="sourceLineNo">050</span>      costsPerGroup[i] = costPerGroup(primariesOfRegionsPerGroup[i]);<a name="line.50"></a>
-<span class="sourceLineNo">051</span>    }<a name="line.51"></a>
-<span class="sourceLineNo">052</span>  }<a name="line.52"></a>
-<span class="sourceLineNo">053</span><a name="line.53"></a>
-<span class="sourceLineNo">054</span>  @Override<a name="line.54"></a>
-<span class="sourceLineNo">055</span>  protected void regionMoved(int region, int oldServer, int newServer) {<a name="line.55"></a>
-<span class="sourceLineNo">056</span>    if (maxCost &lt;= 0) {<a name="line.56"></a>
-<span class="sourceLineNo">057</span>      return; // no need to compute<a name="line.57"></a>
-<span class="sourceLineNo">058</span>    }<a name="line.58"></a>
-<span class="sourceLineNo">059</span>    if (cluster.multiServersPerHost) {<a name="line.59"></a>
-<span class="sourceLineNo">060</span>      int oldHost = cluster.serverIndexToHostIndex[oldServer];<a name="line.60"></a>
-<span class="sourceLineNo">061</span>      int newHost = cluster.serverIndexToHostIndex[newServer];<a name="line.61"></a>
-<span class="sourceLineNo">062</span>      if (newHost != oldHost) {<a name="line.62"></a>
-<span class="sourceLineNo">063</span>        costsPerGroup[oldHost] = costPerGroup(cluster.primariesOfRegionsPerHost[oldHost]);<a name="line.63"></a>
-<span class="sourceLineNo">064</span>        costsPerGroup[newHost] = costPerGroup(cluster.primariesOfRegionsPerHost[newHost]);<a name="line.64"></a>
-<span class="sourceLineNo">065</span>      }<a name="line.65"></a>
-<span class="sourceLineNo">066</span>    } else {<a name="line.66"></a>
-<span class="sourceLineNo">067</span>      costsPerGroup[oldServer] = costPerGroup(cluster.primariesOfRegionsPerServer[oldServer]);<a name="line.67"></a>
-<span class="sourceLineNo">068</span>      costsPerGroup[newServer] = costPerGroup(cluster.primariesOfRegionsPerServer[newServer]);<a name="line.68"></a>
-<span class="sourceLineNo">069</span>    }<a name="line.69"></a>
-<span class="sourceLineNo">070</span>  }<a name="line.70"></a>
-<span class="sourceLineNo">071</span>}<a name="line.71"></a>
+<span class="sourceLineNo">020</span>import org.agrona.collections.Int2IntCounterMap;<a name="line.20"></a>
+<span class="sourceLineNo">021</span>import org.apache.hadoop.conf.Configuration;<a name="line.21"></a>
+<span class="sourceLineNo">022</span>import org.apache.yetus.audience.InterfaceAudience;<a name="line.22"></a>
+<span class="sourceLineNo">023</span><a name="line.23"></a>
+<span class="sourceLineNo">024</span>/**<a name="line.24"></a>
+<span class="sourceLineNo">025</span> * A cost function for region replicas. We give a very high cost to hosting replicas of the same<a name="line.25"></a>
+<span class="sourceLineNo">026</span> * region in the same host. We do not prevent the case though, since if numReplicas &gt;<a name="line.26"></a>
+<span class="sourceLineNo">027</span> * numRegionServers, we still want to keep the replica open.<a name="line.27"></a>
+<span class="sourceLineNo">028</span> */<a name="line.28"></a>
+<span class="sourceLineNo">029</span>@InterfaceAudience.Private<a name="line.29"></a>
+<span class="sourceLineNo">030</span>class RegionReplicaHostCostFunction extends RegionReplicaGroupingCostFunction {<a name="line.30"></a>
+<span class="sourceLineNo">031</span><a name="line.31"></a>
+<span class="sourceLineNo">032</span>  private static final String REGION_REPLICA_HOST_COST_KEY =<a name="line.32"></a>
+<span class="sourceLineNo">033</span>    "hbase.master.balancer.stochastic.regionReplicaHostCostKey";<a name="line.33"></a>
+<span class="sourceLineNo">034</span>  private static final float DEFAULT_REGION_REPLICA_HOST_COST_KEY = 100000;<a name="line.34"></a>
+<span class="sourceLineNo">035</span><a name="line.35"></a>
+<span class="sourceLineNo">036</span>  private Int2IntCounterMap[] colocatedReplicaCountsPerGroup;<a name="line.36"></a>
+<span class="sourceLineNo">037</span><a name="line.37"></a>
+<span class="sourceLineNo">038</span>  public RegionReplicaHostCostFunction(Configuration conf) {<a name="line.38"></a>
+<span class="sourceLineNo">039</span>    this.setMultiplier(<a name="line.39"></a>
+<span class="sourceLineNo">040</span>      conf.getFloat(REGION_REPLICA_HOST_COST_KEY, DEFAULT_REGION_REPLICA_HOST_COST_KEY));<a name="line.40"></a>
+<span class="sourceLineNo">041</span>  }<a name="line.41"></a>
+<span class="sourceLineNo">042</span><a name="line.42"></a>
+<span class="sourceLineNo">043</span>  @Override<a name="line.43"></a>
+<span class="sourceLineNo">044</span>  protected void loadCosts() {<a name="line.44"></a>
+<span class="sourceLineNo">045</span>    // max cost is the case where every region replica is hosted together regardless of host<a name="line.45"></a>
+<span class="sourceLineNo">046</span>    maxCost = cluster.numHosts &gt; 1 ? getMaxCost(cluster) : 0;<a name="line.46"></a>
+<span class="sourceLineNo">047</span>    costsPerGroup = new long[cluster.numHosts];<a name="line.47"></a>
+<span class="sourceLineNo">048</span>    // either server based or host based<a name="line.48"></a>
+<span class="sourceLineNo">049</span>    colocatedReplicaCountsPerGroup = cluster.multiServersPerHost<a name="line.49"></a>
+<span class="sourceLineNo">050</span>      ? cluster.colocatedReplicaCountsPerHost : cluster.colocatedReplicaCountsPerServer;<a name="line.50"></a>
+<span class="sourceLineNo">051</span>    for (int i = 0; i &lt; colocatedReplicaCountsPerGroup.length; i++) {<a name="line.51"></a>
+<span class="sourceLineNo">052</span>      costsPerGroup[i] = costPerGroup(colocatedReplicaCountsPerGroup[i]);<a name="line.52"></a>
+<span class="sourceLineNo">053</span>    }<a name="line.53"></a>
+<span class="sourceLineNo">054</span>  }<a name="line.54"></a>
+<span class="sourceLineNo">055</span><a name="line.55"></a>
+<span class="sourceLineNo">056</span>  @Override<a name="line.56"></a>
+<span class="sourceLineNo">057</span>  protected void regionMoved(int region, int oldServer, int newServer) {<a name="line.57"></a>
+<span class="sourceLineNo">058</span>    if (maxCost &lt;= 0) {<a name="line.58"></a>
+<span class="sourceLineNo">059</span>      return; // no need to compute<a name="line.59"></a>
+<span class="sourceLineNo">060</span>    }<a name="line.60"></a>
+<span class="sourceLineNo">061</span>    if (cluster.multiServersPerHost) {<a name="line.61"></a>
+<span class="sourceLineNo">062</span>      int oldHost = cluster.serverIndexToHostIndex[oldServer];<a name="line.62"></a>
+<span class="sourceLineNo">063</span>      int newHost = cluster.serverIndexToHostIndex[newServer];<a name="line.63"></a>
+<span class="sourceLineNo">064</span>      if (newHost != oldHost) {<a name="line.64"></a>
+<span class="sourceLineNo">065</span>        costsPerGroup[oldHost] = costPerGroup(cluster.colocatedReplicaCountsPerHost[oldHost]);<a name="line.65"></a>
+<span class="sourceLineNo">066</span>        costsPerGroup[newHost] = costPerGroup(cluster.colocatedReplicaCountsPerHost[newHost]);<a name="line.66"></a>
+<span class="sourceLineNo">067</span>      }<a name="line.67"></a>
+<span class="sourceLineNo">068</span>    } else {<a name="line.68"></a>
+<span class="sourceLineNo">069</span>      costsPerGroup[oldServer] = costPerGroup(cluster.colocatedReplicaCountsPerServer[oldServer]);<a name="line.69"></a>
+<span class="sourceLineNo">070</span>      costsPerGroup[newServer] = costPerGroup(cluster.colocatedReplicaCountsPerServer[newServer]);<a name="line.70"></a>
+<span class="sourceLineNo">071</span>    }<a name="line.71"></a>
+<span class="sourceLineNo">072</span>  }<a name="line.72"></a>
+<span class="sourceLineNo">073</span>}<a name="line.73"></a>
 
 
 
diff --git a/devapidocs/src-html/org/apache/hadoop/hbase/master/balancer/RegionReplicaRackCandidateGenerator.html b/devapidocs/src-html/org/apache/hadoop/hbase/master/balancer/RegionReplicaRackCandidateGenerator.html
index 38f4646..ec0d4ef 100644
--- a/devapidocs/src-html/org/apache/hadoop/hbase/master/balancer/RegionReplicaRackCandidateGenerator.html
+++ b/devapidocs/src-html/org/apache/hadoop/hbase/master/balancer/RegionReplicaRackCandidateGenerator.html
@@ -41,7 +41,7 @@
 <span class="sourceLineNo">033</span>      return super.generate(cluster);<a name="line.33"></a>
 <span class="sourceLineNo">034</span>    }<a name="line.34"></a>
 <span class="sourceLineNo">035</span><a name="line.35"></a>
-<span class="sourceLineNo">036</span>    int regionIndex = selectCoHostedRegionPerGroup(cluster.primariesOfRegionsPerRack[rackIndex],<a name="line.36"></a>
+<span class="sourceLineNo">036</span>    int regionIndex = selectCoHostedRegionPerGroup(cluster.colocatedReplicaCountsPerRack[rackIndex],<a name="line.36"></a>
 <span class="sourceLineNo">037</span>      cluster.regionsPerRack[rackIndex], cluster.regionIndexToPrimaryIndex);<a name="line.37"></a>
 <span class="sourceLineNo">038</span><a name="line.38"></a>
 <span class="sourceLineNo">039</span>    // if there are no pairs of region replicas co-hosted, default to random generator<a name="line.39"></a>
diff --git a/devapidocs/src-html/org/apache/hadoop/hbase/master/balancer/RegionReplicaRackCostFunction.html b/devapidocs/src-html/org/apache/hadoop/hbase/master/balancer/RegionReplicaRackCostFunction.html
index 508aefa..9c86e09 100644
--- a/devapidocs/src-html/org/apache/hadoop/hbase/master/balancer/RegionReplicaRackCostFunction.html
+++ b/devapidocs/src-html/org/apache/hadoop/hbase/master/balancer/RegionReplicaRackCostFunction.html
@@ -53,8 +53,8 @@
 <span class="sourceLineNo">045</span>    // max cost is the case where every region replica is hosted together regardless of rack<a name="line.45"></a>
 <span class="sourceLineNo">046</span>    maxCost = getMaxCost(cluster);<a name="line.46"></a>
 <span class="sourceLineNo">047</span>    costsPerGroup = new long[cluster.numRacks];<a name="line.47"></a>
-<span class="sourceLineNo">048</span>    for (int i = 0; i &lt; cluster.primariesOfRegionsPerRack.length; i++) {<a name="line.48"></a>
-<span class="sourceLineNo">049</span>      costsPerGroup[i] = costPerGroup(cluster.primariesOfRegionsPerRack[i]);<a name="line.49"></a>
+<span class="sourceLineNo">048</span>    for (int i = 0; i &lt; cluster.colocatedReplicaCountsPerRack.length; i++) {<a name="line.48"></a>
+<span class="sourceLineNo">049</span>      costsPerGroup[i] = costPerGroup(cluster.colocatedReplicaCountsPerRack[i]);<a name="line.49"></a>
 <span class="sourceLineNo">050</span>    }<a name="line.50"></a>
 <span class="sourceLineNo">051</span>  }<a name="line.51"></a>
 <span class="sourceLineNo">052</span><a name="line.52"></a>
@@ -66,8 +66,8 @@
 <span class="sourceLineNo">058</span>    int oldRack = cluster.serverIndexToRackIndex[oldServer];<a name="line.58"></a>
 <span class="sourceLineNo">059</span>    int newRack = cluster.serverIndexToRackIndex[newServer];<a name="line.59"></a>
 <span class="sourceLineNo">060</span>    if (newRack != oldRack) {<a name="line.60"></a>
-<span class="sourceLineNo">061</span>      costsPerGroup[oldRack] = costPerGroup(cluster.primariesOfRegionsPerRack[oldRack]);<a name="line.61"></a>
-<span class="sourceLineNo">062</span>      costsPerGroup[newRack] = costPerGroup(cluster.primariesOfRegionsPerRack[newRack]);<a name="line.62"></a>
+<span class="sourceLineNo">061</span>      costsPerGroup[oldRack] = costPerGroup(cluster.colocatedReplicaCountsPerRack[oldRack]);<a name="line.61"></a>
+<span class="sourceLineNo">062</span>      costsPerGroup[newRack] = costPerGroup(cluster.colocatedReplicaCountsPerRack[newRack]);<a name="line.62"></a>
 <span class="sourceLineNo">063</span>    }<a name="line.63"></a>
 <span class="sourceLineNo">064</span>  }<a name="line.64"></a>
 <span class="sourceLineNo">065</span>}<a name="line.65"></a>
diff --git a/downloads.html b/downloads.html
index 49c31b5..02eef5b 100644
--- a/downloads.html
+++ b/downloads.html
@@ -457,7 +457,7 @@
         <div class="row">
             <p>Copyright &copy;2007&#x2013;2021
 <a href="https://www.apache.org/">The Apache Software Foundation</a>.
-All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2021-09-22</li>
+All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2021-09-25</li>
 </p>
         </div>
         <p id="poweredBy" class="pull-right"><a href="http://maven.apache.org/" title="Built by Maven" class="poweredBy"><img class="builtBy" alt="Built by Maven" src="./images/logos/maven-feather.png" /></a>
diff --git a/export_control.html b/export_control.html
index 3fb70fc..cc914c8 100644
--- a/export_control.html
+++ b/export_control.html
@@ -186,7 +186,7 @@ for more details.</p>
         <div class="row">
             <p>Copyright &copy;2007&#x2013;2021
 <a href="https://www.apache.org/">The Apache Software Foundation</a>.
-All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2021-09-22</li>
+All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2021-09-25</li>
 </p>
         </div>
         <p id="poweredBy" class="pull-right"><a href="http://maven.apache.org/" title="Built by Maven" class="poweredBy"><img class="builtBy" alt="Built by Maven" src="./images/logos/maven-feather.png" /></a>
diff --git a/index.html b/index.html
index 02fb016..1135c21 100644
--- a/index.html
+++ b/index.html
@@ -264,7 +264,7 @@
         <div class="row">
             <p>Copyright &copy;2007&#x2013;2021
 <a href="https://www.apache.org/">The Apache Software Foundation</a>.
-All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2021-09-22</li>
+All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2021-09-25</li>
 </p>
         </div>
         <p id="poweredBy" class="pull-right"><a href="http://maven.apache.org/" title="Built by Maven" class="poweredBy"><img class="builtBy" alt="Built by Maven" src="./images/logos/maven-feather.png" /></a>
diff --git a/issue-tracking.html b/issue-tracking.html
index 7ca3fea..3c6a90d 100644
--- a/issue-tracking.html
+++ b/issue-tracking.html
@@ -158,7 +158,7 @@
         <div class="row">
             <p>Copyright &copy;2007&#x2013;2021
 <a href="https://www.apache.org/">The Apache Software Foundation</a>.
-All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2021-09-22</li>
+All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2021-09-25</li>
 </p>
         </div>
         <p id="poweredBy" class="pull-right"><a href="http://maven.apache.org/" title="Built by Maven" class="poweredBy"><img class="builtBy" alt="Built by Maven" src="./images/logos/maven-feather.png" /></a>
diff --git a/mail-lists.html b/mail-lists.html
index c90cc2c..c2a50b8 100644
--- a/mail-lists.html
+++ b/mail-lists.html
@@ -204,7 +204,7 @@
         <div class="row">
             <p>Copyright &copy;2007&#x2013;2021
 <a href="https://www.apache.org/">The Apache Software Foundation</a>.
-All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2021-09-22</li>
+All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2021-09-25</li>
 </p>
         </div>
         <p id="poweredBy" class="pull-right"><a href="http://maven.apache.org/" title="Built by Maven" class="poweredBy"><img class="builtBy" alt="Built by Maven" src="./images/logos/maven-feather.png" /></a>
diff --git a/metrics.html b/metrics.html
index f30f94e..2e2ff17 100644
--- a/metrics.html
+++ b/metrics.html
@@ -314,7 +314,7 @@ export HBASE_REGIONSERVER_OPTS=&quot;$HBASE_JMX_OPTS -Dcom.sun.management.jmxrem
         <div class="row">
             <p>Copyright &copy;2007&#x2013;2021
 <a href="https://www.apache.org/">The Apache Software Foundation</a>.
-All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2021-09-22</li>
+All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2021-09-25</li>
 </p>
         </div>
         <p id="poweredBy" class="pull-right"><a href="http://maven.apache.org/" title="Built by Maven" class="poweredBy"><img class="builtBy" alt="Built by Maven" src="./images/logos/maven-feather.png" /></a>
diff --git a/old_news.html b/old_news.html
index 5080811..ba596ba 100644
--- a/old_news.html
+++ b/old_news.html
@@ -305,7 +305,7 @@
         <div class="row">
             <p>Copyright &copy;2007&#x2013;2021
 <a href="https://www.apache.org/">The Apache Software Foundation</a>.
-All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2021-09-22</li>
+All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2021-09-25</li>
 </p>
         </div>
         <p id="poweredBy" class="pull-right"><a href="http://maven.apache.org/" title="Built by Maven" class="poweredBy"><img class="builtBy" alt="Built by Maven" src="./images/logos/maven-feather.png" /></a>
diff --git a/plugin-management.html b/plugin-management.html
index 6903c0f..5923710 100644
--- a/plugin-management.html
+++ b/plugin-management.html
@@ -310,7 +310,7 @@
         <div class="row">
             <p>Copyright &copy;2007&#x2013;2021
 <a href="https://www.apache.org/">The Apache Software Foundation</a>.
-All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2021-09-22</li>
+All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2021-09-25</li>
 </p>
         </div>
         <p id="poweredBy" class="pull-right"><a href="http://maven.apache.org/" title="Built by Maven" class="poweredBy"><img class="builtBy" alt="Built by Maven" src="./images/logos/maven-feather.png" /></a>
diff --git a/plugins.html b/plugins.html
index fe85bba..2648f0a 100644
--- a/plugins.html
+++ b/plugins.html
@@ -237,7 +237,7 @@
         <div class="row">
             <p>Copyright &copy;2007&#x2013;2021
 <a href="https://www.apache.org/">The Apache Software Foundation</a>.
-All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2021-09-22</li>
+All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2021-09-25</li>
 </p>
         </div>
         <p id="poweredBy" class="pull-right"><a href="http://maven.apache.org/" title="Built by Maven" class="poweredBy"><img class="builtBy" alt="Built by Maven" src="./images/logos/maven-feather.png" /></a>
diff --git a/poweredbyhbase.html b/poweredbyhbase.html
index a7cf70a..fc9a3fc 100644
--- a/poweredbyhbase.html
+++ b/poweredbyhbase.html
@@ -639,7 +639,7 @@
         <div class="row">
             <p>Copyright &copy;2007&#x2013;2021
 <a href="https://www.apache.org/">The Apache Software Foundation</a>.
-All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2021-09-22</li>
+All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2021-09-25</li>
 </p>
         </div>
         <p id="poweredBy" class="pull-right"><a href="http://maven.apache.org/" title="Built by Maven" class="poweredBy"><img class="builtBy" alt="Built by Maven" src="./images/logos/maven-feather.png" /></a>
diff --git a/project-info.html b/project-info.html
index 0fe1756..0b0a448 100644
--- a/project-info.html
+++ b/project-info.html
@@ -199,7 +199,7 @@
         <div class="row">
             <p>Copyright &copy;2007&#x2013;2021
 <a href="https://www.apache.org/">The Apache Software Foundation</a>.
-All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2021-09-22</li>
+All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2021-09-25</li>
 </p>
         </div>
         <p id="poweredBy" class="pull-right"><a href="http://maven.apache.org/" title="Built by Maven" class="poweredBy"><img class="builtBy" alt="Built by Maven" src="./images/logos/maven-feather.png" /></a>
diff --git a/project-reports.html b/project-reports.html
index b896886..4ae8196 100644
--- a/project-reports.html
+++ b/project-reports.html
@@ -175,7 +175,7 @@
         <div class="row">
             <p>Copyright &copy;2007&#x2013;2021
 <a href="https://www.apache.org/">The Apache Software Foundation</a>.
-All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2021-09-22</li>
+All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2021-09-25</li>
 </p>
         </div>
         <p id="poweredBy" class="pull-right"><a href="http://maven.apache.org/" title="Built by Maven" class="poweredBy"><img class="builtBy" alt="Built by Maven" src="./images/logos/maven-feather.png" /></a>
diff --git a/project-summary.html b/project-summary.html
index bd10f53..67f80a3 100644
--- a/project-summary.html
+++ b/project-summary.html
@@ -201,7 +201,7 @@
         <div class="row">
             <p>Copyright &copy;2007&#x2013;2021
 <a href="https://www.apache.org/">The Apache Software Foundation</a>.
-All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2021-09-22</li>
+All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2021-09-25</li>
 </p>
         </div>
         <p id="poweredBy" class="pull-right"><a href="http://maven.apache.org/" title="Built by Maven" class="poweredBy"><img class="builtBy" alt="Built by Maven" src="./images/logos/maven-feather.png" /></a>
diff --git a/pseudo-distributed.html b/pseudo-distributed.html
index 2a6ed29..c9ba1e3 100644
--- a/pseudo-distributed.html
+++ b/pseudo-distributed.html
@@ -163,7 +163,7 @@ Running Apache HBase (TM) in pseudo-distributed mode
         <div class="row">
             <p>Copyright &copy;2007&#x2013;2021
 <a href="https://www.apache.org/">The Apache Software Foundation</a>.
-All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2021-09-22</li>
+All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2021-09-25</li>
 </p>
         </div>
         <p id="poweredBy" class="pull-right"><a href="http://maven.apache.org/" title="Built by Maven" class="poweredBy"><img class="builtBy" alt="Built by Maven" src="./images/logos/maven-feather.png" /></a>
diff --git a/replication.html b/replication.html
index 65b00d7..c07d4b5 100644
--- a/replication.html
+++ b/replication.html
@@ -158,7 +158,7 @@
         <div class="row">
             <p>Copyright &copy;2007&#x2013;2021
 <a href="https://www.apache.org/">The Apache Software Foundation</a>.
-All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2021-09-22</li>
+All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2021-09-25</li>
 </p>
         </div>
         <p id="poweredBy" class="pull-right"><a href="http://maven.apache.org/" title="Built by Maven" class="poweredBy"><img class="builtBy" alt="Built by Maven" src="./images/logos/maven-feather.png" /></a>
diff --git a/resources.html b/resources.html
index de5f39b..2ff94dc 100644
--- a/resources.html
+++ b/resources.html
@@ -186,7 +186,7 @@
         <div class="row">
             <p>Copyright &copy;2007&#x2013;2021
 <a href="https://www.apache.org/">The Apache Software Foundation</a>.
-All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2021-09-22</li>
+All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2021-09-25</li>
 </p>
         </div>
         <p id="poweredBy" class="pull-right"><a href="http://maven.apache.org/" title="Built by Maven" class="poweredBy"><img class="builtBy" alt="Built by Maven" src="./images/logos/maven-feather.png" /></a>
diff --git a/source-repository.html b/source-repository.html
index 66abb96..0681260 100644
--- a/source-repository.html
+++ b/source-repository.html
@@ -169,7 +169,7 @@
         <div class="row">
             <p>Copyright &copy;2007&#x2013;2021
 <a href="https://www.apache.org/">The Apache Software Foundation</a>.
-All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2021-09-22</li>
+All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2021-09-25</li>
 </p>
         </div>
         <p id="poweredBy" class="pull-right"><a href="http://maven.apache.org/" title="Built by Maven" class="poweredBy"><img class="builtBy" alt="Built by Maven" src="./images/logos/maven-feather.png" /></a>
diff --git a/sponsors.html b/sponsors.html
index 77073b6..f6276b7 100644
--- a/sponsors.html
+++ b/sponsors.html
@@ -188,7 +188,7 @@
         <div class="row">
             <p>Copyright &copy;2007&#x2013;2021
 <a href="https://www.apache.org/">The Apache Software Foundation</a>.
-All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2021-09-22</li>
+All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2021-09-25</li>
 </p>
         </div>
         <p id="poweredBy" class="pull-right"><a href="http://maven.apache.org/" title="Built by Maven" class="poweredBy"><img class="builtBy" alt="Built by Maven" src="./images/logos/maven-feather.png" /></a>
diff --git a/supportingprojects.html b/supportingprojects.html
index 53a92a1..e6dacc1 100644
--- a/supportingprojects.html
+++ b/supportingprojects.html
@@ -379,7 +379,7 @@
         <div class="row">
             <p>Copyright &copy;2007&#x2013;2021
 <a href="https://www.apache.org/">The Apache Software Foundation</a>.
-All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2021-09-22</li>
+All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2021-09-25</li>
 </p>
         </div>
         <p id="poweredBy" class="pull-right"><a href="http://maven.apache.org/" title="Built by Maven" class="poweredBy"><img class="builtBy" alt="Built by Maven" src="./images/logos/maven-feather.png" /></a>
diff --git a/team-list.html b/team-list.html
index c5a0d58..12c9acb 100644
--- a/team-list.html
+++ b/team-list.html
@@ -732,7 +732,7 @@
         <div class="row">
             <p>Copyright &copy;2007&#x2013;2021
 <a href="https://www.apache.org/">The Apache Software Foundation</a>.
-All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2021-09-22</li>
+All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2021-09-25</li>
 </p>
         </div>
         <p id="poweredBy" class="pull-right"><a href="http://maven.apache.org/" title="Built by Maven" class="poweredBy"><img class="builtBy" alt="Built by Maven" src="./images/logos/maven-feather.png" /></a>
diff --git a/testdevapidocs/org/apache/hadoop/hbase/chaos/actions/package-tree.html b/testdevapidocs/org/apache/hadoop/hbase/chaos/actions/package-tree.html
index d7d9b9a..24c8931 100644
--- a/testdevapidocs/org/apache/hadoop/hbase/chaos/actions/package-tree.html
+++ b/testdevapidocs/org/apache/hadoop/hbase/chaos/actions/package-tree.html
@@ -159,8 +159,8 @@
 <ul>
 <li type="circle">java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Enum.html?is-external=true" title="class or interface in java.lang"><span class="typeNameLink">Enum</span></a>&lt;E&gt; (implements java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Comparable.html?is-external=true" title="class or interface in java.lang">Comparable</a>&lt;T&gt;, java.io.<a href="https://docs.oracle.com/javase/8/docs/api/java/io/Serializable.html?is-external=true [...]
 <ul>
-<li type="circle">org.apache.hadoop.hbase.chaos.actions.<a href="../../../../../../org/apache/hadoop/hbase/chaos/actions/RollingBatchRestartRsAction.KillOrStart.html" title="enum in org.apache.hadoop.hbase.chaos.actions"><span class="typeNameLink">RollingBatchRestartRsAction.KillOrStart</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.chaos.actions.<a href="../../../../../../org/apache/hadoop/hbase/chaos/actions/RollingBatchSuspendResumeRsAction.SuspendOrResume.html" title="enum in org.apache.hadoop.hbase.chaos.actions"><span class="typeNameLink">RollingBatchSuspendResumeRsAction.SuspendOrResume</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.chaos.actions.<a href="../../../../../../org/apache/hadoop/hbase/chaos/actions/RollingBatchRestartRsAction.KillOrStart.html" title="enum in org.apache.hadoop.hbase.chaos.actions"><span class="typeNameLink">RollingBatchRestartRsAction.KillOrStart</span></a></li>
 </ul>
 </li>
 </ul>
diff --git a/testdevapidocs/org/apache/hadoop/hbase/io/hfile/package-tree.html b/testdevapidocs/org/apache/hadoop/hbase/io/hfile/package-tree.html
index fb8b779..8434a98 100644
--- a/testdevapidocs/org/apache/hadoop/hbase/io/hfile/package-tree.html
+++ b/testdevapidocs/org/apache/hadoop/hbase/io/hfile/package-tree.html
@@ -184,8 +184,8 @@
 <ul>
 <li type="circle">java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Enum.html?is-external=true" title="class or interface in java.lang"><span class="typeNameLink">Enum</span></a>&lt;E&gt; (implements java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Comparable.html?is-external=true" title="class or interface in java.lang">Comparable</a>&lt;T&gt;, java.io.<a href="https://docs.oracle.com/javase/8/docs/api/java/io/Serializable.html?is-external=true [...]
 <ul>
-<li type="circle">org.apache.hadoop.hbase.io.hfile.<a href="../../../../../../org/apache/hadoop/hbase/io/hfile/TagUsage.html" title="enum in org.apache.hadoop.hbase.io.hfile"><span class="typeNameLink">TagUsage</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.io.hfile.<a href="../../../../../../org/apache/hadoop/hbase/io/hfile/TestCacheOnWrite.CacheOnWriteType.html" title="enum in org.apache.hadoop.hbase.io.hfile"><span class="typeNameLink">TestCacheOnWrite.CacheOnWriteType</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.io.hfile.<a href="../../../../../../org/apache/hadoop/hbase/io/hfile/TagUsage.html" title="enum in org.apache.hadoop.hbase.io.hfile"><span class="typeNameLink">TagUsage</span></a></li>
 </ul>
 </li>
 </ul>
diff --git a/testdevapidocs/org/apache/hadoop/hbase/master/balancer/TestStochasticLoadBalancer.MockCluster.html b/testdevapidocs/org/apache/hadoop/hbase/master/balancer/TestStochasticLoadBalancer.MockCluster.html
index e2cfdb5..32b7f79 100644
--- a/testdevapidocs/org/apache/hadoop/hbase/master/balancer/TestStochasticLoadBalancer.MockCluster.html
+++ b/testdevapidocs/org/apache/hadoop/hbase/master/balancer/TestStochasticLoadBalancer.MockCluster.html
@@ -161,89 +161,89 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/TestStochasticLoadBalancer.MockCluster.html#clusterState">clusterState</a></span></code>&nbsp;</td>
 </tr>
 <tr class="rowColor">
+<td class="colFirst"><code>(package private) org.agrona.collections.Int2IntCounterMap[]</code></td>
+<td class="colLast"><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/TestStochasticLoadBalancer.MockCluster.html#colocatedReplicaCountsPerHost">colocatedReplicaCountsPerHost</a></span></code>&nbsp;</td>
+</tr>
+<tr class="altColor">
+<td class="colFirst"><code>(package private) org.agrona.collections.Int2IntCounterMap[]</code></td>
+<td class="colLast"><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/TestStochasticLoadBalancer.MockCluster.html#colocatedReplicaCountsPerRack">colocatedReplicaCountsPerRack</a></span></code>&nbsp;</td>
+</tr>
+<tr class="rowColor">
+<td class="colFirst"><code>(package private) org.agrona.collections.Int2IntCounterMap[]</code></td>
+<td class="colLast"><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/TestStochasticLoadBalancer.MockCluster.html#colocatedReplicaCountsPerServer">colocatedReplicaCountsPerServer</a></span></code>&nbsp;</td>
+</tr>
+<tr class="altColor">
 <td class="colFirst"><code>(package private) boolean</code></td>
 <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/TestStochasticLoadBalancer.MockCluster.html#hasRegionReplicas">hasRegionReplicas</a></span></code>&nbsp;</td>
 </tr>
-<tr class="altColor">
+<tr class="rowColor">
 <td class="colFirst"><code>(package private) <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a>[]</code></td>
 <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/TestStochasticLoadBalancer.MockCluster.html#hosts">hosts</a></span></code>&nbsp;</td>
 </tr>
-<tr class="rowColor">
+<tr class="altColor">
 <td class="colFirst"><code>(package private) <a href="https://docs.oracle.com/javase/8/docs/api/java/util/Map.html?is-external=true" title="class or interface in java.util">Map</a>&lt;<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a>,<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Integer.html?is-external=true" title="class or interface in java.lang">Integer</a>&gt;</code></td>
 <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/TestStochasticLoadBalancer.MockCluster.html#hostsToIndex">hostsToIndex</a></span></code>&nbsp;</td>
 </tr>
-<tr class="altColor">
+<tr class="rowColor">
 <td class="colFirst"><code>(package private) int[]</code></td>
 <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/TestStochasticLoadBalancer.MockCluster.html#initialRegionIndexToServerIndex">initialRegionIndexToServerIndex</a></span></code>&nbsp;</td>
 </tr>
-<tr class="rowColor">
+<tr class="altColor">
 <td class="colFirst"><code>private int[][]</code></td>
 <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/TestStochasticLoadBalancer.MockCluster.html#localities">localities</a></span></code>&nbsp;</td>
 </tr>
-<tr class="altColor">
+<tr class="rowColor">
 <td class="colFirst"><code>(package private) float[]</code></td>
 <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/TestStochasticLoadBalancer.MockCluster.html#localityPerServer">localityPerServer</a></span></code>&nbsp;</td>
 </tr>
-<tr class="rowColor">
+<tr class="altColor">
 <td class="colFirst"><code>(package private) double[]</code></td>
 <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/TestStochasticLoadBalancer.MockCluster.html#maxRegionSkewByTable">maxRegionSkewByTable</a></span></code>&nbsp;</td>
 </tr>
-<tr class="altColor">
+<tr class="rowColor">
 <td class="colFirst"><code>(package private) double[]</code></td>
 <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/TestStochasticLoadBalancer.MockCluster.html#meanRegionsPerTable">meanRegionsPerTable</a></span></code>&nbsp;</td>
 </tr>
-<tr class="rowColor">
+<tr class="altColor">
 <td class="colFirst"><code>(package private) double[]</code></td>
 <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/TestStochasticLoadBalancer.MockCluster.html#minRegionSkewByTable">minRegionSkewByTable</a></span></code>&nbsp;</td>
 </tr>
-<tr class="altColor">
+<tr class="rowColor">
 <td class="colFirst"><code>(package private) boolean</code></td>
 <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/TestStochasticLoadBalancer.MockCluster.html#multiServersPerHost">multiServersPerHost</a></span></code>&nbsp;</td>
 </tr>
-<tr class="rowColor">
+<tr class="altColor">
 <td class="colFirst"><code>(package private) int</code></td>
 <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/TestStochasticLoadBalancer.MockCluster.html#numHosts">numHosts</a></span></code>&nbsp;</td>
 </tr>
-<tr class="altColor">
+<tr class="rowColor">
 <td class="colFirst"><code>(package private) int</code></td>
 <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/TestStochasticLoadBalancer.MockCluster.html#numMovedRegions">numMovedRegions</a></span></code>&nbsp;</td>
 </tr>
-<tr class="rowColor">
+<tr class="altColor">
 <td class="colFirst"><code>(package private) int</code></td>
 <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/TestStochasticLoadBalancer.MockCluster.html#numRacks">numRacks</a></span></code>&nbsp;</td>
 </tr>
-<tr class="altColor">
+<tr class="rowColor">
 <td class="colFirst"><code>(package private) int</code></td>
 <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/TestStochasticLoadBalancer.MockCluster.html#numRegions">numRegions</a></span></code>&nbsp;</td>
 </tr>
-<tr class="rowColor">
+<tr class="altColor">
 <td class="colFirst"><code>(package private) int[][]</code></td>
 <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/TestStochasticLoadBalancer.MockCluster.html#numRegionsPerServerPerTable">numRegionsPerServerPerTable</a></span></code>&nbsp;</td>
 </tr>
-<tr class="altColor">
+<tr class="rowColor">
 <td class="colFirst"><code>(package private) int[]</code></td>
 <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/TestStochasticLoadBalancer.MockCluster.html#numRegionsPerTable">numRegionsPerTable</a></span></code>&nbsp;</td>
 </tr>
-<tr class="rowColor">
+<tr class="altColor">
 <td class="colFirst"><code>(package private) int</code></td>
 <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/TestStochasticLoadBalancer.MockCluster.html#numServers">numServers</a></span></code>&nbsp;</td>
 </tr>
-<tr class="altColor">
+<tr class="rowColor">
 <td class="colFirst"><code>(package private) int</code></td>
 <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/TestStochasticLoadBalancer.MockCluster.html#numTables">numTables</a></span></code>&nbsp;</td>
 </tr>
-<tr class="rowColor">
-<td class="colFirst"><code>(package private) int[][]</code></td>
-<td class="colLast"><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/TestStochasticLoadBalancer.MockCluster.html#primariesOfRegionsPerHost">primariesOfRegionsPerHost</a></span></code>&nbsp;</td>
-</tr>
-<tr class="altColor">
-<td class="colFirst"><code>(package private) int[][]</code></td>
-<td class="colLast"><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/TestStochasticLoadBalancer.MockCluster.html#primariesOfRegionsPerRack">primariesOfRegionsPerRack</a></span></code>&nbsp;</td>
-</tr>
-<tr class="rowColor">
-<td class="colFirst"><code>(package private) int[][]</code></td>
-<td class="colLast"><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/TestStochasticLoadBalancer.MockCluster.html#primariesOfRegionsPerServer">primariesOfRegionsPerServer</a></span></code>&nbsp;</td>
-</tr>
 <tr class="altColor">
 <td class="colFirst"><code>(package private) <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a>[]</code></td>
 <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/TestStochasticLoadBalancer.MockCluster.html#racks">racks</a></span></code>&nbsp;</td>
@@ -636,31 +636,31 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <pre>int[][] <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#line.0">regionsPerRack</a></pre>
 </li>
 </ul>
-<a name="primariesOfRegionsPerServer">
+<a name="colocatedReplicaCountsPerServer">
 <!--   -->
 </a>
 <ul class="blockList">
 <li class="blockList">
-<h4>primariesOfRegionsPerServer</h4>
-<pre>int[][] <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#line.0">primariesOfRegionsPerServer</a></pre>
+<h4>colocatedReplicaCountsPerServer</h4>
+<pre>org.agrona.collections.Int2IntCounterMap[] <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#line.0">colocatedReplicaCountsPerServer</a></pre>
 </li>
 </ul>
-<a name="primariesOfRegionsPerHost">
+<a name="colocatedReplicaCountsPerHost">
 <!--   -->
 </a>
 <ul class="blockList">
 <li class="blockList">
-<h4>primariesOfRegionsPerHost</h4>
-<pre>int[][] <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#line.0">primariesOfRegionsPerHost</a></pre>
+<h4>colocatedReplicaCountsPerHost</h4>
+<pre>org.agrona.collections.Int2IntCounterMap[] <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#line.0">colocatedReplicaCountsPerHost</a></pre>
 </li>
 </ul>
-<a name="primariesOfRegionsPerRack">
+<a name="colocatedReplicaCountsPerRack">
 <!--   -->
 </a>
 <ul class="blockList">
 <li class="blockList">
-<h4>primariesOfRegionsPerRack</h4>
-<pre>int[][] <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#line.0">primariesOfRegionsPerRack</a></pre>
+<h4>colocatedReplicaCountsPerRack</h4>
+<pre>org.agrona.collections.Int2IntCounterMap[] <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/BalancerClusterState.html#line.0">colocatedReplicaCountsPerRack</a></pre>
 </li>
 </ul>
 <a name="serversPerHost">
diff --git a/testdevapidocs/org/apache/hadoop/hbase/package-tree.html b/testdevapidocs/org/apache/hadoop/hbase/package-tree.html
index 222eaa2..ffde45f 100644
--- a/testdevapidocs/org/apache/hadoop/hbase/package-tree.html
+++ b/testdevapidocs/org/apache/hadoop/hbase/package-tree.html
@@ -665,19 +665,19 @@
 <ul>
 <li type="circle">java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Enum.html?is-external=true" title="class or interface in java.lang"><span class="typeNameLink">Enum</span></a>&lt;E&gt; (implements java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Comparable.html?is-external=true" title="class or interface in java.lang">Comparable</a>&lt;T&gt;, java.io.<a href="https://docs.oracle.com/javase/8/docs/api/java/io/Serializable.html?is-external=true [...]
 <ul>
-<li type="circle">org.apache.hadoop.hbase.<a href="../../../../org/apache/hadoop/hbase/RESTApiClusterManager.RoleCommand.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">RESTApiClusterManager.RoleCommand</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.<a href="../../../../org/apache/hadoop/hbase/ScanPerformanceEvaluation.ScanCounter.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">ScanPerformanceEvaluation.ScanCounter</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.<a href="../../../../org/apache/hadoop/hbase/PerformanceEvaluation.Counter.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">PerformanceEvaluation.Counter</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.<a href="../../../../org/apache/hadoop/hbase/RESTApiClusterManager.Service.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">RESTApiClusterManager.Service</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.<a href="../../../../org/apache/hadoop/hbase/IntegrationTestDDLMasterFailover.ACTION.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">IntegrationTestDDLMasterFailover.ACTION</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.<a href="../../../../org/apache/hadoop/hbase/RESTApiClusterManager.RoleState.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">RESTApiClusterManager.RoleState</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.<a href="../../../../org/apache/hadoop/hbase/ClusterManager.ServiceType.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">ClusterManager.ServiceType</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.<a href="../../../../org/apache/hadoop/hbase/HBaseClusterManager.Signal.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">HBaseClusterManager.Signal</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.<a href="../../../../org/apache/hadoop/hbase/IntegrationTestDDLMasterFailover.ACTION.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">IntegrationTestDDLMasterFailover.ACTION</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.<a href="../../../../org/apache/hadoop/hbase/RESTApiClusterManager.Service.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">RESTApiClusterManager.Service</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.<a href="../../../../org/apache/hadoop/hbase/ZNodeClusterManager.CmdType.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">ZNodeClusterManager.CmdType</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.<a href="../../../../org/apache/hadoop/hbase/PerformanceEvaluation.Counter.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">PerformanceEvaluation.Counter</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.<a href="../../../../org/apache/hadoop/hbase/IntegrationTestRegionReplicaPerf.Stat.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">IntegrationTestRegionReplicaPerf.Stat</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.<a href="../../../../org/apache/hadoop/hbase/RESTApiClusterManager.HealthSummary.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">RESTApiClusterManager.HealthSummary</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.<a href="../../../../org/apache/hadoop/hbase/RESTApiClusterManager.RoleCommand.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">RESTApiClusterManager.RoleCommand</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.<a href="../../../../org/apache/hadoop/hbase/HBaseClusterManager.CommandProvider.Operation.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">HBaseClusterManager.CommandProvider.Operation</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.<a href="../../../../org/apache/hadoop/hbase/RESTApiClusterManager.RoleState.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">RESTApiClusterManager.RoleState</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.<a href="../../../../org/apache/hadoop/hbase/IntegrationTestRegionReplicaPerf.Stat.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">IntegrationTestRegionReplicaPerf.Stat</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.<a href="../../../../org/apache/hadoop/hbase/ResourceChecker.Phase.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">ResourceChecker.Phase</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.<a href="../../../../org/apache/hadoop/hbase/ClusterManager.ServiceType.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">ClusterManager.ServiceType</span></a></li>
 </ul>
 </li>
 </ul>
diff --git a/testdevapidocs/org/apache/hadoop/hbase/procedure/package-tree.html b/testdevapidocs/org/apache/hadoop/hbase/procedure/package-tree.html
index 3ce38a7..4309238 100644
--- a/testdevapidocs/org/apache/hadoop/hbase/procedure/package-tree.html
+++ b/testdevapidocs/org/apache/hadoop/hbase/procedure/package-tree.html
@@ -81,14 +81,14 @@
 <ul>
 <li type="circle">java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang"><span class="typeNameLink">Object</span></a>
 <ul>
-<li type="circle">org.apache.hadoop.hbase.procedure2.Procedure&lt;TEnvironment&gt; (implements java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Comparable.html?is-external=true" title="class or interface in java.lang">Comparable</a>&lt;T&gt;)
+<li type="circle">org.apache.hadoop.hbase.procedure.Procedure (implements java.util.concurrent.<a href="https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/Callable.html?is-external=true" title="class or interface in java.util.concurrent">Callable</a>&lt;V&gt;, org.apache.hadoop.hbase.errorhandling.ForeignExceptionListener)
 <ul>
-<li type="circle">org.apache.hadoop.hbase.procedure.<a href="../../../../../org/apache/hadoop/hbase/procedure/TestProcedureDescriber.TestProcedure.html" title="class in org.apache.hadoop.hbase.procedure"><span class="typeNameLink">TestProcedureDescriber.TestProcedure</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.procedure.<a href="../../../../../org/apache/hadoop/hbase/procedure/TestProcedure.LatchedProcedure.html" title="class in org.apache.hadoop.hbase.procedure"><span class="typeNameLink">TestProcedure.LatchedProcedure</span></a></li>
 </ul>
 </li>
-<li type="circle">org.apache.hadoop.hbase.procedure.Procedure (implements java.util.concurrent.<a href="https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/Callable.html?is-external=true" title="class or interface in java.util.concurrent">Callable</a>&lt;V&gt;, org.apache.hadoop.hbase.errorhandling.ForeignExceptionListener)
+<li type="circle">org.apache.hadoop.hbase.procedure2.Procedure&lt;TEnvironment&gt; (implements java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Comparable.html?is-external=true" title="class or interface in java.lang">Comparable</a>&lt;T&gt;)
 <ul>
-<li type="circle">org.apache.hadoop.hbase.procedure.<a href="../../../../../org/apache/hadoop/hbase/procedure/TestProcedure.LatchedProcedure.html" title="class in org.apache.hadoop.hbase.procedure"><span class="typeNameLink">TestProcedure.LatchedProcedure</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.procedure.<a href="../../../../../org/apache/hadoop/hbase/procedure/TestProcedureDescriber.TestProcedure.html" title="class in org.apache.hadoop.hbase.procedure"><span class="typeNameLink">TestProcedureDescriber.TestProcedure</span></a></li>
 </ul>
 </li>
 <li type="circle">org.apache.hadoop.hbase.procedure.ProcedureManager
diff --git a/testdevapidocs/org/apache/hadoop/hbase/procedure2/package-tree.html b/testdevapidocs/org/apache/hadoop/hbase/procedure2/package-tree.html
index c772984..9ef4361 100644
--- a/testdevapidocs/org/apache/hadoop/hbase/procedure2/package-tree.html
+++ b/testdevapidocs/org/apache/hadoop/hbase/procedure2/package-tree.html
@@ -242,9 +242,9 @@
 <li type="circle">java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Enum.html?is-external=true" title="class or interface in java.lang"><span class="typeNameLink">Enum</span></a>&lt;E&gt; (implements java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Comparable.html?is-external=true" title="class or interface in java.lang">Comparable</a>&lt;T&gt;, java.io.<a href="https://docs.oracle.com/javase/8/docs/api/java/io/Serializable.html?is-external=true [...]
 <ul>
 <li type="circle">org.apache.hadoop.hbase.procedure2.<a href="../../../../../org/apache/hadoop/hbase/procedure2/TestStateMachineProcedure.TestSMProcedureState.html" title="enum in org.apache.hadoop.hbase.procedure2"><span class="typeNameLink">TestStateMachineProcedure.TestSMProcedureState</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.procedure2.<a href="../../../../../org/apache/hadoop/hbase/procedure2/TestProcedureRecovery.TestStateMachineProcedure.State.html" title="enum in org.apache.hadoop.hbase.procedure2"><span class="typeNameLink">TestProcedureRecovery.TestStateMachineProcedure.State</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.procedure2.<a href="../../../../../org/apache/hadoop/hbase/procedure2/TestProcedureBypass.StuckStateMachineState.html" title="enum in org.apache.hadoop.hbase.procedure2"><span class="typeNameLink">TestProcedureBypass.StuckStateMachineState</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.procedure2.<a href="../../../../../org/apache/hadoop/hbase/procedure2/TestYieldProcedures.TestStateMachineProcedure.State.html" title="enum in org.apache.hadoop.hbase.procedure2"><span class="typeNameLink">TestYieldProcedures.TestStateMachineProcedure.State</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.procedure2.<a href="../../../../../org/apache/hadoop/hbase/procedure2/TestProcedureRecovery.TestStateMachineProcedure.State.html" title="enum in org.apache.hadoop.hbase.procedure2"><span class="typeNameLink">TestProcedureRecovery.TestStateMachineProcedure.State</span></a></li>
 </ul>
 </li>
 </ul>
diff --git a/testdevapidocs/org/apache/hadoop/hbase/regionserver/package-tree.html b/testdevapidocs/org/apache/hadoop/hbase/regionserver/package-tree.html
index 41f1e33..4428086 100644
--- a/testdevapidocs/org/apache/hadoop/hbase/regionserver/package-tree.html
+++ b/testdevapidocs/org/apache/hadoop/hbase/regionserver/package-tree.html
@@ -734,12 +734,12 @@
 <ul>
 <li type="circle">java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Enum.html?is-external=true" title="class or interface in java.lang"><span class="typeNameLink">Enum</span></a>&lt;E&gt; (implements java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Comparable.html?is-external=true" title="class or interface in java.lang">Comparable</a>&lt;T&gt;, java.io.<a href="https://docs.oracle.com/javase/8/docs/api/java/io/Serializable.html?is-external=true [...]
 <ul>
-<li type="circle">org.apache.hadoop.hbase.regionserver.<a href="../../../../../org/apache/hadoop/hbase/regionserver/TestRegionServerReadRequestMetrics.Metric.html" title="enum in org.apache.hadoop.hbase.regionserver"><span class="typeNameLink">TestRegionServerReadRequestMetrics.Metric</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.regionserver.<a href="../../../../../org/apache/hadoop/hbase/regionserver/TestCacheOnWriteInSchema.CacheOnWriteType.html" title="enum in org.apache.hadoop.hbase.regionserver"><span class="typeNameLink">TestCacheOnWriteInSchema.CacheOnWriteType</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.regionserver.<a href="../../../../../org/apache/hadoop/hbase/regionserver/TestMultiLogThreshold.ActionType.html" title="enum in org.apache.hadoop.hbase.regionserver"><span class="typeNameLink">TestMultiLogThreshold.ActionType</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.regionserver.<a href="../../../../../org/apache/hadoop/hbase/regionserver/TestCompactionState.StateSource.html" title="enum in org.apache.hadoop.hbase.regionserver"><span class="typeNameLink">TestCompactionState.StateSource</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.regionserver.<a href="../../../../../org/apache/hadoop/hbase/regionserver/TestAtomicOperation.TestStep.html" title="enum in org.apache.hadoop.hbase.regionserver"><span class="typeNameLink">TestAtomicOperation.TestStep</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.regionserver.<a href="../../../../../org/apache/hadoop/hbase/regionserver/TestCacheOnWriteInSchema.CacheOnWriteType.html" title="enum in org.apache.hadoop.hbase.regionserver"><span class="typeNameLink">TestCacheOnWriteInSchema.CacheOnWriteType</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.regionserver.<a href="../../../../../org/apache/hadoop/hbase/regionserver/DataBlockEncodingTool.Manipulation.html" title="enum in org.apache.hadoop.hbase.regionserver"><span class="typeNameLink">DataBlockEncodingTool.Manipulation</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.regionserver.<a href="../../../../../org/apache/hadoop/hbase/regionserver/TestCompactionState.StateSource.html" title="enum in org.apache.hadoop.hbase.regionserver"><span class="typeNameLink">TestCompactionState.StateSource</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.regionserver.<a href="../../../../../org/apache/hadoop/hbase/regionserver/TestRegionServerReadRequestMetrics.Metric.html" title="enum in org.apache.hadoop.hbase.regionserver"><span class="typeNameLink">TestRegionServerReadRequestMetrics.Metric</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.regionserver.<a href="../../../../../org/apache/hadoop/hbase/regionserver/TestMultiLogThreshold.ActionType.html" title="enum in org.apache.hadoop.hbase.regionserver"><span class="typeNameLink">TestMultiLogThreshold.ActionType</span></a></li>
 </ul>
 </li>
 </ul>
diff --git a/testdevapidocs/org/apache/hadoop/hbase/test/package-tree.html b/testdevapidocs/org/apache/hadoop/hbase/test/package-tree.html
index 3192189..ff43980 100644
--- a/testdevapidocs/org/apache/hadoop/hbase/test/package-tree.html
+++ b/testdevapidocs/org/apache/hadoop/hbase/test/package-tree.html
@@ -260,11 +260,11 @@
 <ul>
 <li type="circle">java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Enum.html?is-external=true" title="class or interface in java.lang"><span class="typeNameLink">Enum</span></a>&lt;E&gt; (implements java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Comparable.html?is-external=true" title="class or interface in java.lang">Comparable</a>&lt;T&gt;, java.io.<a href="https://docs.oracle.com/javase/8/docs/api/java/io/Serializable.html?is-external=true [...]
 <ul>
-<li type="circle">org.apache.hadoop.hbase.test.<a href="../../../../../org/apache/hadoop/hbase/test/IntegrationTestBigLinkedList.Generator.Counts.html" title="enum in org.apache.hadoop.hbase.test"><span class="typeNameLink">IntegrationTestBigLinkedList.Generator.Counts</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.test.<a href="../../../../../org/apache/hadoop/hbase/test/IntegrationTestBigLinkedList.Verify.Counts.html" title="enum in org.apache.hadoop.hbase.test"><span class="typeNameLink">IntegrationTestBigLinkedList.Verify.Counts</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.test.<a href="../../../../../org/apache/hadoop/hbase/test/IntegrationTestLoadCommonCrawl.Counts.html" title="enum in org.apache.hadoop.hbase.test"><span class="typeNameLink">IntegrationTestLoadCommonCrawl.Counts</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.test.<a href="../../../../../org/apache/hadoop/hbase/test/IntegrationTestWithCellVisibilityLoadAndVerify.Counters.html" title="enum in org.apache.hadoop.hbase.test"><span class="typeNameLink">IntegrationTestWithCellVisibilityLoadAndVerify.Counters</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.test.<a href="../../../../../org/apache/hadoop/hbase/test/IntegrationTestLoadAndVerify.Counters.html" title="enum in org.apache.hadoop.hbase.test"><span class="typeNameLink">IntegrationTestLoadAndVerify.Counters</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.test.<a href="../../../../../org/apache/hadoop/hbase/test/IntegrationTestWithCellVisibilityLoadAndVerify.Counters.html" title="enum in org.apache.hadoop.hbase.test"><span class="typeNameLink">IntegrationTestWithCellVisibilityLoadAndVerify.Counters</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.test.<a href="../../../../../org/apache/hadoop/hbase/test/IntegrationTestBigLinkedList.Verify.Counts.html" title="enum in org.apache.hadoop.hbase.test"><span class="typeNameLink">IntegrationTestBigLinkedList.Verify.Counts</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.test.<a href="../../../../../org/apache/hadoop/hbase/test/IntegrationTestBigLinkedList.Generator.Counts.html" title="enum in org.apache.hadoop.hbase.test"><span class="typeNameLink">IntegrationTestBigLinkedList.Generator.Counts</span></a></li>
 </ul>
 </li>
 </ul>
diff --git a/testdevapidocs/org/apache/hadoop/hbase/wal/package-tree.html b/testdevapidocs/org/apache/hadoop/hbase/wal/package-tree.html
index 27f9c56..12bf261 100644
--- a/testdevapidocs/org/apache/hadoop/hbase/wal/package-tree.html
+++ b/testdevapidocs/org/apache/hadoop/hbase/wal/package-tree.html
@@ -201,9 +201,9 @@
 <ul>
 <li type="circle">java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Enum.html?is-external=true" title="class or interface in java.lang"><span class="typeNameLink">Enum</span></a>&lt;E&gt; (implements java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Comparable.html?is-external=true" title="class or interface in java.lang">Comparable</a>&lt;T&gt;, java.io.<a href="https://docs.oracle.com/javase/8/docs/api/java/io/Serializable.html?is-external=true [...]
 <ul>
-<li type="circle">org.apache.hadoop.hbase.wal.<a href="../../../../../org/apache/hadoop/hbase/wal/FaultyFSLog.FailureType.html" title="enum in org.apache.hadoop.hbase.wal"><span class="typeNameLink">FaultyFSLog.FailureType</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.wal.<a href="../../../../../org/apache/hadoop/hbase/wal/TestWALSplit.Corruptions.html" title="enum in org.apache.hadoop.hbase.wal"><span class="typeNameLink">TestWALSplit.Corruptions</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.wal.<a href="../../../../../org/apache/hadoop/hbase/wal/IOTestProvider.AllowedOperations.html" title="enum in org.apache.hadoop.hbase.wal"><span class="typeNameLink">IOTestProvider.AllowedOperations</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.wal.<a href="../../../../../org/apache/hadoop/hbase/wal/FaultyFSLog.FailureType.html" title="enum in org.apache.hadoop.hbase.wal"><span class="typeNameLink">FaultyFSLog.FailureType</span></a></li>
 </ul>
 </li>
 </ul>
diff --git a/testdevapidocs/src-html/org/apache/hadoop/hbase/master/balancer/TestStochasticLoadBalancerRegionReplicaWithRacks.ForTestRackManager.html b/testdevapidocs/src-html/org/apache/hadoop/hbase/master/balancer/TestStochasticLoadBalancerRegionReplicaWithRacks.ForTestRackManager.html
index 293f628..4b093e55 100644
--- a/testdevapidocs/src-html/org/apache/hadoop/hbase/master/balancer/TestStochasticLoadBalancerRegionReplicaWithRacks.ForTestRackManager.html
+++ b/testdevapidocs/src-html/org/apache/hadoop/hbase/master/balancer/TestStochasticLoadBalancerRegionReplicaWithRacks.ForTestRackManager.html
@@ -63,12 +63,12 @@
 <span class="sourceLineNo">055</span>    conf.setFloat("hbase.master.balancer.stochastic.maxMovePercent", 1.0f);<a name="line.55"></a>
 <span class="sourceLineNo">056</span>    conf.setLong("hbase.master.balancer.stochastic.maxRunningTime", 120 * 1000); // 120 sec<a name="line.56"></a>
 <span class="sourceLineNo">057</span>    loadBalancer.onConfigurationChange(conf);<a name="line.57"></a>
-<span class="sourceLineNo">058</span>    int numNodes = 30;<a name="line.58"></a>
-<span class="sourceLineNo">059</span>    int numRegions = numNodes * 30;<a name="line.59"></a>
+<span class="sourceLineNo">058</span>    int numNodes = 4;<a name="line.58"></a>
+<span class="sourceLineNo">059</span>    int numRegions = numNodes * 1;<a name="line.59"></a>
 <span class="sourceLineNo">060</span>    int replication = 3; // 3 replicas per region<a name="line.60"></a>
-<span class="sourceLineNo">061</span>    int numRegionsPerServer = 28;<a name="line.61"></a>
-<span class="sourceLineNo">062</span>    int numTables = 10;<a name="line.62"></a>
-<span class="sourceLineNo">063</span>    int numRacks = 4; // all replicas should be on a different rack<a name="line.63"></a>
+<span class="sourceLineNo">061</span>    int numRegionsPerServer = 1;<a name="line.61"></a>
+<span class="sourceLineNo">062</span>    int numTables = 1;<a name="line.62"></a>
+<span class="sourceLineNo">063</span>    int numRacks = 3; // all replicas should be on a different rack<a name="line.63"></a>
 <span class="sourceLineNo">064</span>    Map&lt;ServerName, List&lt;RegionInfo&gt;&gt; serverMap =<a name="line.64"></a>
 <span class="sourceLineNo">065</span>        createServerMap(numNodes, numRegions, numRegionsPerServer, replication, numTables);<a name="line.65"></a>
 <span class="sourceLineNo">066</span>    RackManager rm = new ForTestRackManager(numRacks);<a name="line.66"></a>
diff --git a/testdevapidocs/src-html/org/apache/hadoop/hbase/master/balancer/TestStochasticLoadBalancerRegionReplicaWithRacks.html b/testdevapidocs/src-html/org/apache/hadoop/hbase/master/balancer/TestStochasticLoadBalancerRegionReplicaWithRacks.html
index 293f628..4b093e55 100644
--- a/testdevapidocs/src-html/org/apache/hadoop/hbase/master/balancer/TestStochasticLoadBalancerRegionReplicaWithRacks.html
+++ b/testdevapidocs/src-html/org/apache/hadoop/hbase/master/balancer/TestStochasticLoadBalancerRegionReplicaWithRacks.html
@@ -63,12 +63,12 @@
 <span class="sourceLineNo">055</span>    conf.setFloat("hbase.master.balancer.stochastic.maxMovePercent", 1.0f);<a name="line.55"></a>
 <span class="sourceLineNo">056</span>    conf.setLong("hbase.master.balancer.stochastic.maxRunningTime", 120 * 1000); // 120 sec<a name="line.56"></a>
 <span class="sourceLineNo">057</span>    loadBalancer.onConfigurationChange(conf);<a name="line.57"></a>
-<span class="sourceLineNo">058</span>    int numNodes = 30;<a name="line.58"></a>
-<span class="sourceLineNo">059</span>    int numRegions = numNodes * 30;<a name="line.59"></a>
+<span class="sourceLineNo">058</span>    int numNodes = 4;<a name="line.58"></a>
+<span class="sourceLineNo">059</span>    int numRegions = numNodes * 1;<a name="line.59"></a>
 <span class="sourceLineNo">060</span>    int replication = 3; // 3 replicas per region<a name="line.60"></a>
-<span class="sourceLineNo">061</span>    int numRegionsPerServer = 28;<a name="line.61"></a>
-<span class="sourceLineNo">062</span>    int numTables = 10;<a name="line.62"></a>
-<span class="sourceLineNo">063</span>    int numRacks = 4; // all replicas should be on a different rack<a name="line.63"></a>
+<span class="sourceLineNo">061</span>    int numRegionsPerServer = 1;<a name="line.61"></a>
+<span class="sourceLineNo">062</span>    int numTables = 1;<a name="line.62"></a>
+<span class="sourceLineNo">063</span>    int numRacks = 3; // all replicas should be on a different rack<a name="line.63"></a>
 <span class="sourceLineNo">064</span>    Map&lt;ServerName, List&lt;RegionInfo&gt;&gt; serverMap =<a name="line.64"></a>
 <span class="sourceLineNo">065</span>        createServerMap(numNodes, numRegions, numRegionsPerServer, replication, numTables);<a name="line.65"></a>
 <span class="sourceLineNo">066</span>    RackManager rm = new ForTestRackManager(numRacks);<a name="line.66"></a>