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 2019/10/05 14:43:47 UTC

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

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 de63ec9  Published site at f69e7705e075df0744bde61cc29682468f2e431f.
de63ec9 is described below

commit de63ec9eaf6a8b927da9370f745697216ab98ff9
Author: jenkins <bu...@apache.org>
AuthorDate: Sat Oct 5 14:43:36 2019 +0000

    Published site at f69e7705e075df0744bde61cc29682468f2e431f.
---
 acid-semantics.html                                |    2 +-
 apache_hbase_reference_guide.pdf                   |    4 +-
 book.html                                          |    2 +-
 bulk-loads.html                                    |    2 +-
 checkstyle-aggregate.html                          |  124 +-
 coc.html                                           |    2 +-
 dependencies.html                                  |    2 +-
 dependency-convergence.html                        |    2 +-
 dependency-info.html                               |    2 +-
 dependency-management.html                         |    2 +-
 devapidocs/constant-values.html                    |    4 +-
 ...ochasticLoadBalancer.CPRequestCostFunction.html |   10 +-
 .../StochasticLoadBalancer.CandidateGenerator.html |   22 +-
 ...dBalancer.CostFromRegionLoadAsRateFunction.html |    6 +-
 ...ticLoadBalancer.CostFromRegionLoadFunction.html |   20 +-
 .../StochasticLoadBalancer.CostFunction.html       |   28 +-
 ...chasticLoadBalancer.LoadCandidateGenerator.html |   10 +-
 ...adBalancer.LocalityBasedCandidateGenerator.html |   14 +-
 ...sticLoadBalancer.LocalityBasedCostFunction.html |   26 +-
 ...asticLoadBalancer.MemStoreSizeCostFunction.html |   10 +-
 .../StochasticLoadBalancer.MoveCostFunction.html   |   18 +-
 ...alancer.PrimaryRegionCountSkewCostFunction.html |   12 +-
 ...asticLoadBalancer.RackLocalityCostFunction.html |   10 +-
 ...asticLoadBalancer.RandomCandidateGenerator.html |    6 +-
 ...hasticLoadBalancer.ReadRequestCostFunction.html |   10 +-
 ...icLoadBalancer.RegionCountSkewCostFunction.html |   12 +-
 ...adBalancer.RegionReplicaCandidateGenerator.html |   10 +-
 ...LoadBalancer.RegionReplicaHostCostFunction.html |   26 +-
 ...lancer.RegionReplicaRackCandidateGenerator.html |    6 +-
 ...LoadBalancer.RegionReplicaRackCostFunction.html |   12 +-
 ...ticLoadBalancer.ServerLocalityCostFunction.html |   10 +-
 ...ochasticLoadBalancer.StoreFileCostFunction.html |   10 +-
 ...ochasticLoadBalancer.TableSkewCostFunction.html |   10 +-
 ...asticLoadBalancer.WriteRequestCostFunction.html |   10 +-
 .../master/balancer/StochasticLoadBalancer.html    |   24 +-
 .../src-html/org/apache/hadoop/hbase/Version.html  |    4 +-
 ...ochasticLoadBalancer.CPRequestCostFunction.html | 2814 ++++++++++----------
 .../StochasticLoadBalancer.CandidateGenerator.html | 2814 ++++++++++----------
 ...dBalancer.CostFromRegionLoadAsRateFunction.html | 2814 ++++++++++----------
 ...ticLoadBalancer.CostFromRegionLoadFunction.html | 2814 ++++++++++----------
 .../StochasticLoadBalancer.CostFunction.html       | 2814 ++++++++++----------
 ...chasticLoadBalancer.LoadCandidateGenerator.html | 2814 ++++++++++----------
 ...adBalancer.LocalityBasedCandidateGenerator.html | 2814 ++++++++++----------
 ...sticLoadBalancer.LocalityBasedCostFunction.html | 2814 ++++++++++----------
 ...asticLoadBalancer.MemStoreSizeCostFunction.html | 2814 ++++++++++----------
 .../StochasticLoadBalancer.MoveCostFunction.html   | 2814 ++++++++++----------
 ...alancer.PrimaryRegionCountSkewCostFunction.html | 2814 ++++++++++----------
 ...asticLoadBalancer.RackLocalityCostFunction.html | 2814 ++++++++++----------
 ...asticLoadBalancer.RandomCandidateGenerator.html | 2814 ++++++++++----------
 ...hasticLoadBalancer.ReadRequestCostFunction.html | 2814 ++++++++++----------
 ...icLoadBalancer.RegionCountSkewCostFunction.html | 2814 ++++++++++----------
 ...adBalancer.RegionReplicaCandidateGenerator.html | 2814 ++++++++++----------
 ...LoadBalancer.RegionReplicaHostCostFunction.html | 2814 ++++++++++----------
 ...lancer.RegionReplicaRackCandidateGenerator.html | 2814 ++++++++++----------
 ...LoadBalancer.RegionReplicaRackCostFunction.html | 2814 ++++++++++----------
 ...ticLoadBalancer.ServerLocalityCostFunction.html | 2814 ++++++++++----------
 ...ochasticLoadBalancer.StoreFileCostFunction.html | 2814 ++++++++++----------
 ...ochasticLoadBalancer.TableSkewCostFunction.html | 2814 ++++++++++----------
 ...asticLoadBalancer.WriteRequestCostFunction.html | 2814 ++++++++++----------
 .../master/balancer/StochasticLoadBalancer.html    | 2814 ++++++++++----------
 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 +-
 .../TestStochasticLoadBalancer.MockCluster.html    |   10 +-
 .../balancer/TestStochasticLoadBalancer.html       |   38 +-
 .../TestStochasticLoadBalancer.MockCluster.html    |  930 +++----
 .../balancer/TestStochasticLoadBalancer.html       |  930 +++----
 84 files changed, 35018 insertions(+), 34950 deletions(-)

diff --git a/acid-semantics.html b/acid-semantics.html
index b1b87d7..cc748d0 100644
--- a/acid-semantics.html
+++ b/acid-semantics.html
@@ -443,7 +443,7 @@
         <div class="row">
             <p>Copyright &copy;2007&#x2013;2019
 <a href="https://www.apache.org/">The Apache Software Foundation</a>.
-All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2019-10-04</li>
+All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2019-10-05</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 04079ca..6683e70 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.0.alpha.15, based on Prawn 2.2.2)
 /Producer (Apache HBase Team)
-/ModDate (D:20191004143845+00'00')
-/CreationDate (D:20191004143845+00'00')
+/ModDate (D:20191005144033+00'00')
+/CreationDate (D:20191005144033+00'00')
 >>
 endobj
 2 0 obj
diff --git a/book.html b/book.html
index 559c467..6ef2b04 100644
--- a/book.html
+++ b/book.html
@@ -43140,7 +43140,7 @@ org/apache/hadoop/hbase/security/access/AccessControlClient.revoke:(Lorg/apache/
 <div id="footer">
 <div id="footer-text">
 Version 3.0.0-SNAPSHOT<br>
-Last updated 2019-10-04 14:29:52 UTC
+Last updated 2019-10-05 14:29:57 UTC
 </div>
 </div>
 </body>
diff --git a/bulk-loads.html b/bulk-loads.html
index b443668..43cb4a3 100644
--- a/bulk-loads.html
+++ b/bulk-loads.html
@@ -148,7 +148,7 @@
         <div class="row">
             <p>Copyright &copy;2007&#x2013;2019
 <a href="https://www.apache.org/">The Apache Software Foundation</a>.
-All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2019-10-04</li>
+All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2019-10-05</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 154b694..cb48b6f 100644
--- a/checkstyle-aggregate.html
+++ b/checkstyle-aggregate.html
@@ -50667,169 +50667,169 @@
 <td>blocks</td>
 <td>NeedBraces</td>
 <td>'if' construct must use '{}'s.</td>
-<td>505</td></tr>
+<td>507</td></tr>
 <tr class="a">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>blocks</td>
 <td>NeedBraces</td>
 <td>'if' construct must use '{}'s.</td>
-<td>613</td></tr>
+<td>615</td></tr>
 <tr class="b">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>sizes</td>
 <td>LineLength</td>
 <td>Line is longer than 100 characters (found 107).</td>
-<td>846</td></tr>
+<td>848</td></tr>
 <tr class="a">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>sizes</td>
 <td>LineLength</td>
 <td>Line is longer than 100 characters (found 109).</td>
-<td>862</td></tr>
+<td>864</td></tr>
 <tr class="b">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>sizes</td>
 <td>LineLength</td>
 <td>Line is longer than 100 characters (found 116).</td>
-<td>876</td></tr>
+<td>878</td></tr>
 <tr class="a">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>sizes</td>
 <td>LineLength</td>
 <td>Line is longer than 100 characters (found 114).</td>
-<td>880</td></tr>
+<td>882</td></tr>
 <tr class="b">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>javadoc</td>
 <td>JavadocTagContinuationIndentation</td>
 <td>Line continuation have incorrect indentation level, expected level should be 2.</td>
-<td>911</td></tr>
+<td>913</td></tr>
 <tr class="a">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>indentation</td>
 <td>Indentation</td>
 <td>'case' child has incorrect indentation level 6, expected level should be 8.</td>
-<td>1052</td></tr>
+<td>1054</td></tr>
 <tr class="b">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>indentation</td>
 <td>Indentation</td>
 <td>'case' child has incorrect indentation level 6, expected level should be 8.</td>
-<td>1053</td></tr>
+<td>1055</td></tr>
 <tr class="a">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>indentation</td>
 <td>Indentation</td>
 <td>'block' child has incorrect indentation level 8, expected level should be 10.</td>
-<td>1054</td></tr>
+<td>1056</td></tr>
 <tr class="b">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>indentation</td>
 <td>Indentation</td>
 <td>'block' child has incorrect indentation level 8, expected level should be 10.</td>
-<td>1055</td></tr>
+<td>1057</td></tr>
 <tr class="a">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>indentation</td>
 <td>Indentation</td>
 <td>'block' child has incorrect indentation level 8, expected level should be 10.</td>
-<td>1056</td></tr>
+<td>1058</td></tr>
 <tr class="b">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>indentation</td>
 <td>Indentation</td>
 <td>'case' child has incorrect indentation level 6, expected level should be 8.</td>
-<td>1057</td></tr>
+<td>1059</td></tr>
 <tr class="a">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>indentation</td>
 <td>Indentation</td>
 <td>'block' child has incorrect indentation level 8, expected level should be 10.</td>
-<td>1058</td></tr>
+<td>1060</td></tr>
 <tr class="b">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>indentation</td>
 <td>Indentation</td>
 <td>'block' child has incorrect indentation level 8, expected level should be 10.</td>
-<td>1059</td></tr>
+<td>1061</td></tr>
 <tr class="a">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>indentation</td>
 <td>Indentation</td>
 <td>'block' child has incorrect indentation level 8, expected level should be 10.</td>
-<td>1060</td></tr>
+<td>1062</td></tr>
 <tr class="b">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>indentation</td>
 <td>Indentation</td>
 <td>'case' child has incorrect indentation level 6, expected level should be 8.</td>
-<td>1061</td></tr>
+<td>1063</td></tr>
 <tr class="a">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>indentation</td>
 <td>Indentation</td>
 <td>'block' child has incorrect indentation level 8, expected level should be 10.</td>
-<td>1062</td></tr>
+<td>1064</td></tr>
 <tr class="b">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>indentation</td>
 <td>Indentation</td>
 <td>'block' child has incorrect indentation level 8, expected level should be 10.</td>
-<td>1063</td></tr>
+<td>1065</td></tr>
 <tr class="a">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>indentation</td>
 <td>Indentation</td>
 <td>'block' child has incorrect indentation level 8, expected level should be 10.</td>
-<td>1064</td></tr>
+<td>1066</td></tr>
 <tr class="b">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>indentation</td>
 <td>Indentation</td>
 <td>'block' child has incorrect indentation level 8, expected level should be 10.</td>
-<td>1065</td></tr>
+<td>1067</td></tr>
 <tr class="a">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>indentation</td>
 <td>Indentation</td>
 <td>'case' child has incorrect indentation level 6, expected level should be 8.</td>
-<td>1066</td></tr>
+<td>1068</td></tr>
 <tr class="b">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>indentation</td>
 <td>Indentation</td>
 <td>'block' child has incorrect indentation level 8, expected level should be 10.</td>
-<td>1067</td></tr>
+<td>1069</td></tr>
 <tr class="a">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>blocks</td>
 <td>NeedBraces</td>
 <td>'if' construct must use '{}'s.</td>
-<td>1140</td></tr>
+<td>1142</td></tr>
 <tr class="b">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>sizes</td>
 <td>LineLength</td>
 <td>Line is longer than 100 characters (found 106).</td>
-<td>1347</td></tr>
+<td>1349</td></tr>
 <tr class="a">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>sizes</td>
 <td>LineLength</td>
 <td>Line is longer than 100 characters (found 106).</td>
-<td>1348</td></tr>
+<td>1350</td></tr>
 <tr class="b">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>sizes</td>
 <td>LineLength</td>
 <td>Line is longer than 100 characters (found 109).</td>
-<td>1352</td></tr>
+<td>1354</td></tr>
 <tr class="a">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>sizes</td>
 <td>LineLength</td>
 <td>Line is longer than 100 characters (found 109).</td>
-<td>1395</td></tr></table></div>
+<td>1397</td></tr></table></div>
 <div class="section">
 <h3 id="org.apache.hadoop.hbase.master.balancer.TestBalancerStatusTagInJMXMetrics.java">org/apache/hadoop/hbase/master/balancer/TestBalancerStatusTagInJMXMetrics.java</h3>
 <table border="0" class="table table-striped">
@@ -51384,199 +51384,199 @@
 <td>indentation</td>
 <td>Indentation</td>
 <td>'array initialization' child has incorrect indentation level 6, expected level should be 4.</td>
-<td>79</td></tr>
+<td>80</td></tr>
 <tr class="a">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>indentation</td>
 <td>Indentation</td>
 <td>'array initialization' child has incorrect indentation level 10, expected level should be 8.</td>
-<td>80</td></tr>
+<td>81</td></tr>
 <tr class="b">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>indentation</td>
 <td>Indentation</td>
 <td>'array initialization' child has incorrect indentation level 10, expected level should be 8.</td>
-<td>81</td></tr>
+<td>82</td></tr>
 <tr class="a">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>indentation</td>
 <td>Indentation</td>
 <td>'array initialization' child has incorrect indentation level 10, expected level should be 8.</td>
-<td>82</td></tr>
+<td>83</td></tr>
 <tr class="b">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>indentation</td>
 <td>Indentation</td>
 <td>'array initialization' child has incorrect indentation level 10, expected level should be 8.</td>
-<td>83</td></tr>
+<td>84</td></tr>
 <tr class="a">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>indentation</td>
 <td>Indentation</td>
 <td>'array initialization' child has incorrect indentation level 10, expected level should be 8.</td>
-<td>84</td></tr>
+<td>85</td></tr>
 <tr class="b">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>indentation</td>
 <td>Indentation</td>
 <td>'array initialization' child has incorrect indentation level 6, expected level should be 4.</td>
-<td>88</td></tr>
+<td>89</td></tr>
 <tr class="a">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>indentation</td>
 <td>Indentation</td>
 <td>'array initialization' child has incorrect indentation level 10, expected level should be 8.</td>
-<td>89</td></tr>
+<td>90</td></tr>
 <tr class="b">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>indentation</td>
 <td>Indentation</td>
 <td>'array initialization' child has incorrect indentation level 10, expected level should be 8.</td>
-<td>90</td></tr>
+<td>91</td></tr>
 <tr class="a">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>indentation</td>
 <td>Indentation</td>
 <td>'array initialization' child has incorrect indentation level 10, expected level should be 8.</td>
-<td>91</td></tr>
+<td>92</td></tr>
 <tr class="b">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>indentation</td>
 <td>Indentation</td>
 <td>'array initialization' child has incorrect indentation level 10, expected level should be 8.</td>
-<td>92</td></tr>
+<td>93</td></tr>
 <tr class="a">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>indentation</td>
 <td>Indentation</td>
 <td>'array initialization' child has incorrect indentation level 10, expected level should be 8.</td>
-<td>93</td></tr>
+<td>94</td></tr>
 <tr class="b">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>indentation</td>
 <td>Indentation</td>
 <td>'array initialization' child has incorrect indentation level 6, expected level should be 4.</td>
-<td>97</td></tr>
+<td>98</td></tr>
 <tr class="a">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>indentation</td>
 <td>Indentation</td>
 <td>'array initialization' child has incorrect indentation level 10, expected level should be 8.</td>
-<td>98</td></tr>
+<td>99</td></tr>
 <tr class="b">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>indentation</td>
 <td>Indentation</td>
 <td>'array initialization' child has incorrect indentation level 10, expected level should be 8.</td>
-<td>99</td></tr>
+<td>100</td></tr>
 <tr class="a">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>indentation</td>
 <td>Indentation</td>
 <td>'array initialization' child has incorrect indentation level 10, expected level should be 8.</td>
-<td>100</td></tr>
+<td>101</td></tr>
 <tr class="b">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>indentation</td>
 <td>Indentation</td>
 <td>'array initialization' child has incorrect indentation level 10, expected level should be 8.</td>
-<td>101</td></tr>
+<td>102</td></tr>
 <tr class="a">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>indentation</td>
 <td>Indentation</td>
 <td>'array initialization' child has incorrect indentation level 10, expected level should be 8.</td>
-<td>102</td></tr>
+<td>103</td></tr>
 <tr class="b">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>sizes</td>
 <td>LineLength</td>
 <td>Line is longer than 100 characters (found 101).</td>
-<td>105</td></tr>
+<td>106</td></tr>
 <tr class="a">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>indentation</td>
 <td>Indentation</td>
 <td>'array initialization' child has incorrect indentation level 6, expected level should be 4.</td>
-<td>106</td></tr>
+<td>107</td></tr>
 <tr class="b">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>indentation</td>
 <td>Indentation</td>
 <td>'array initialization' child has incorrect indentation level 10, expected level should be 8.</td>
-<td>107</td></tr>
+<td>108</td></tr>
 <tr class="a">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>indentation</td>
 <td>Indentation</td>
 <td>'array initialization' child has incorrect indentation level 10, expected level should be 8.</td>
-<td>108</td></tr>
+<td>109</td></tr>
 <tr class="b">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>indentation</td>
 <td>Indentation</td>
 <td>'array initialization' child has incorrect indentation level 10, expected level should be 8.</td>
-<td>109</td></tr>
+<td>110</td></tr>
 <tr class="a">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>indentation</td>
 <td>Indentation</td>
 <td>'array initialization' child has incorrect indentation level 10, expected level should be 8.</td>
-<td>110</td></tr>
+<td>111</td></tr>
 <tr class="b">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>indentation</td>
 <td>Indentation</td>
 <td>'array initialization' child has incorrect indentation level 10, expected level should be 8.</td>
-<td>111</td></tr>
+<td>112</td></tr>
 <tr class="a">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>sizes</td>
 <td>LineLength</td>
 <td>Line is longer than 100 characters (found 111).</td>
-<td>114</td></tr>
+<td>115</td></tr>
 <tr class="b">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>indentation</td>
 <td>Indentation</td>
 <td>'array initialization' child has incorrect indentation level 6, expected level should be 4.</td>
-<td>115</td></tr>
+<td>116</td></tr>
 <tr class="a">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>indentation</td>
 <td>Indentation</td>
 <td>'array initialization' child has incorrect indentation level 10, expected level should be 8.</td>
-<td>116</td></tr>
+<td>117</td></tr>
 <tr class="b">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>indentation</td>
 <td>Indentation</td>
 <td>'array initialization' child has incorrect indentation level 10, expected level should be 8.</td>
-<td>117</td></tr>
+<td>118</td></tr>
 <tr class="a">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>indentation</td>
 <td>Indentation</td>
 <td>'array initialization' child has incorrect indentation level 10, expected level should be 8.</td>
-<td>118</td></tr>
+<td>119</td></tr>
 <tr class="b">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>indentation</td>
 <td>Indentation</td>
 <td>'array initialization' child has incorrect indentation level 10, expected level should be 8.</td>
-<td>119</td></tr>
+<td>120</td></tr>
 <tr class="a">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>indentation</td>
 <td>Indentation</td>
 <td>'array initialization' child has incorrect indentation level 10, expected level should be 8.</td>
-<td>120</td></tr>
+<td>121</td></tr>
 <tr class="b">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>sizes</td>
 <td>LineLength</td>
 <td>Line is longer than 100 characters (found 107).</td>
-<td>490</td></tr></table></div>
+<td>500</td></tr></table></div>
 <div class="section">
 <h3 id="org.apache.hadoop.hbase.master.cleaner.BaseFileCleanerDelegate.java">org/apache/hadoop/hbase/master/cleaner/BaseFileCleanerDelegate.java</h3>
 <table border="0" class="table table-striped">
@@ -92796,7 +92796,7 @@
         <div class="row">
             <p>Copyright &copy;2007&#x2013;2019
 <a href="https://www.apache.org/">The Apache Software Foundation</a>.
-All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2019-10-04</li>
+All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2019-10-05</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 21e8f19..34a9dc4 100644
--- a/coc.html
+++ b/coc.html
@@ -217,7 +217,7 @@ email to <a class="externalLink" href="mailto:private@hbase.apache.org">the priv
         <div class="row">
             <p>Copyright &copy;2007&#x2013;2019
 <a href="https://www.apache.org/">The Apache Software Foundation</a>.
-All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2019-10-04</li>
+All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2019-10-05</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 0df07da..1cec9e6 100644
--- a/dependencies.html
+++ b/dependencies.html
@@ -289,7 +289,7 @@
         <div class="row">
             <p>Copyright &copy;2007&#x2013;2019
 <a href="https://www.apache.org/">The Apache Software Foundation</a>.
-All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2019-10-04</li>
+All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2019-10-05</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 9fdafc9..03ce117 100644
--- a/dependency-convergence.html
+++ b/dependency-convergence.html
@@ -534,7 +534,7 @@
         <div class="row">
             <p>Copyright &copy;2007&#x2013;2019
 <a href="https://www.apache.org/">The Apache Software Foundation</a>.
-All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2019-10-04</li>
+All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2019-10-05</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 7e1a41e..e4546b8 100644
--- a/dependency-info.html
+++ b/dependency-info.html
@@ -170,7 +170,7 @@
         <div class="row">
             <p>Copyright &copy;2007&#x2013;2019
 <a href="https://www.apache.org/">The Apache Software Foundation</a>.
-All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2019-10-04</li>
+All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2019-10-05</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 299f642..1bdb0a4 100644
--- a/dependency-management.html
+++ b/dependency-management.html
@@ -892,7 +892,7 @@
         <div class="row">
             <p>Copyright &copy;2007&#x2013;2019
 <a href="https://www.apache.org/">The Apache Software Foundation</a>.
-All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2019-10-04</li>
+All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2019-10-05</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/constant-values.html b/devapidocs/constant-values.html
index 2444783..7bc8760 100644
--- a/devapidocs/constant-values.html
+++ b/devapidocs/constant-values.html
@@ -3999,14 +3999,14 @@
 <!--   -->
 </a><code>public&nbsp;static&nbsp;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></code></td>
 <td><code><a href="org/apache/hadoop/hbase/Version.html#date">date</a></code></td>
-<td class="colLast"><code>"Fri Oct  4 14:35:04 UTC 2019"</code></td>
+<td class="colLast"><code>"Sat Oct  5 14:36:31 UTC 2019"</code></td>
 </tr>
 <tr class="rowColor">
 <td class="colFirst"><a name="org.apache.hadoop.hbase.Version.revision">
 <!--   -->
 </a><code>public&nbsp;static&nbsp;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></code></td>
 <td><code><a href="org/apache/hadoop/hbase/Version.html#revision">revision</a></code></td>
-<td class="colLast"><code>"800c35a30e647ee6a87bab67b528e2634b38d0c4"</code></td>
+<td class="colLast"><code>"f69e7705e075df0744bde61cc29682468f2e431f"</code></td>
 </tr>
 <tr class="altColor">
 <td class="colFirst"><a name="org.apache.hadoop.hbase.Version.srcChecksum">
diff --git a/devapidocs/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CPRequestCostFunction.html b/devapidocs/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CPRequestCostFunction.html
index 7903e9e..e83ea2f 100644
--- a/devapidocs/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CPRequestCostFunction.html
+++ b/devapidocs/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CPRequestCostFunction.html
@@ -128,7 +128,7 @@ var activeTableTab = "activeTableTab";
 </dl>
 <hr>
 <br>
-<pre>static class <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.html#line.1534">StochasticLoadBalancer.CPRequestCostFunction</a>
+<pre>static class <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.html#line.1536">StochasticLoadBalancer.CPRequestCostFunction</a>
 extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CostFromRegionLoadAsRateFunction.html" title="class in org.apache.hadoop.hbase.master.balancer">StochasticLoadBalancer.CostFromRegionLoadAsRateFunction</a></pre>
 <div class="block">Compute the cost of total number of coprocessor requests  The more unbalanced the higher the
  computed cost will be.  This uses a rolling average of regionload.</div>
@@ -250,7 +250,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/Stoch
 <ul class="blockList">
 <li class="blockList">
 <h4>CP_REQUEST_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/StochasticLoadBalancer.CPRequestCostFunction.html#line.1536">CP_REQUEST_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/StochasticLoadBalancer.CPRequestCostFunction.html#line.1538">CP_REQUEST_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.StochasticLoadBalancer.CPRequestCostFunction.CP_REQUEST_COST_KEY">Constant Field Values</a></dd>
@@ -263,7 +263,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/Stoch
 <ul class="blockListLast">
 <li class="blockList">
 <h4>DEFAULT_CP_REQUEST_COST</h4>
-<pre>private static final&nbsp;float <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CPRequestCostFunction.html#line.1538">DEFAULT_CP_REQUEST_COST</a></pre>
+<pre>private static final&nbsp;float <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CPRequestCostFunction.html#line.1540">DEFAULT_CP_REQUEST_COST</a></pre>
 <dl>
 <dt><span class="seeLabel">See Also:</span></dt>
 <dd><a href="../../../../../../constant-values.html#org.apache.hadoop.hbase.master.balancer.StochasticLoadBalancer.CPRequestCostFunction.DEFAULT_CP_REQUEST_COST">Constant Field Values</a></dd>
@@ -284,7 +284,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/Stoch
 <ul class="blockListLast">
 <li class="blockList">
 <h4>CPRequestCostFunction</h4>
-<pre><a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CPRequestCostFunction.html#line.1540">CPRequestCostFunction</a>(org.apache.hadoop.conf.Configuration&nbsp;conf)</pre>
+<pre><a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CPRequestCostFunction.html#line.1542">CPRequestCostFunction</a>(org.apache.hadoop.conf.Configuration&nbsp;conf)</pre>
 </li>
 </ul>
 </li>
@@ -301,7 +301,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/Stoch
 <ul class="blockListLast">
 <li class="blockList">
 <h4>getCostFromRl</h4>
-<pre>protected&nbsp;double&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CPRequestCostFunction.html#line.1546">getCostFromRl</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BalancerRegionLoad.html" title="class in org.apache.hadoop.hbase.master.balancer">BalancerRegionLoad</a>&nbsp;rl)</pre>
+<pre>protected&nbsp;double&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CPRequestCostFunction.html#line.1548">getCostFromRl</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BalancerRegionLoad.html" title="class in org.apache.hadoop.hbase.master.balancer">BalancerRegionLoad</a>&nbsp;rl)</pre>
 <dl>
 <dt><span class="overrideSpecifyLabel">Specified by:</span></dt>
 <dd><code><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CostFromRegionLoadFunction.html#getCostFromRl-org.apache.hadoop.hbase.master.balancer.BalancerRegionLoad-">getCostFromRl</a></code>&nbsp;in class&nbsp;<code><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CostFromRegionLoadFunction.html" title="class in org.apache.hadoop.hbase.master.balancer">StochasticLoadBalancer.CostFromRegionLoadFunction</a></ [...]
diff --git a/devapidocs/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CandidateGenerator.html b/devapidocs/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CandidateGenerator.html
index cac2ff0..56b6b7a 100644
--- a/devapidocs/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CandidateGenerator.html
+++ b/devapidocs/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CandidateGenerator.html
@@ -117,7 +117,7 @@ var activeTableTab = "activeTableTab";
 </dl>
 <hr>
 <br>
-<pre>abstract static class <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.html#line.658">StochasticLoadBalancer.CandidateGenerator</a>
+<pre>abstract static class <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.html#line.660">StochasticLoadBalancer.CandidateGenerator</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">Generates a candidate action to be applied to the cluster for cost function search</div>
 </li>
@@ -232,7 +232,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockListLast">
 <li class="blockList">
 <h4>CandidateGenerator</h4>
-<pre><a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CandidateGenerator.html#line.658">CandidateGenerator</a>()</pre>
+<pre><a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CandidateGenerator.html#line.660">CandidateGenerator</a>()</pre>
 </li>
 </ul>
 </li>
@@ -249,7 +249,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>generate</h4>
-<pre>abstract&nbsp;<a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BaseLoadBalancer.Cluster.Action.html" title="class in org.apache.hadoop.hbase.master.balancer">BaseLoadBalancer.Cluster.Action</a>&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CandidateGenerator.html#line.659">generate</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BaseLoadBalancer.Cluster.html" title="class in org.apache [...]
+<pre>abstract&nbsp;<a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BaseLoadBalancer.Cluster.Action.html" title="class in org.apache.hadoop.hbase.master.balancer">BaseLoadBalancer.Cluster.Action</a>&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CandidateGenerator.html#line.661">generate</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BaseLoadBalancer.Cluster.html" title="class in org.apache [...]
 </li>
 </ul>
 <a name="pickRandomRegion-org.apache.hadoop.hbase.master.balancer.BaseLoadBalancer.Cluster-int-double-">
@@ -258,7 +258,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>pickRandomRegion</h4>
-<pre>protected&nbsp;int&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CandidateGenerator.html#line.673">pickRandomRegion</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BaseLoadBalancer.Cluster.html" title="class in org.apache.hadoop.hbase.master.balancer">BaseLoadBalancer.Cluster</a>&nbsp;cluster,
+<pre>protected&nbsp;int&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CandidateGenerator.html#line.675">pickRandomRegion</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BaseLoadBalancer.Cluster.html" title="class in org.apache.hadoop.hbase.master.balancer">BaseLoadBalancer.Cluster</a>&nbsp;cluster,
                                int&nbsp;server,
                                double&nbsp;chanceOfNoSwap)</pre>
 <div class="block">From a list of regions pick a random one. Null can be returned which
@@ -282,7 +282,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>pickRandomServer</h4>
-<pre>protected&nbsp;int&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CandidateGenerator.html#line.683">pickRandomServer</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BaseLoadBalancer.Cluster.html" title="class in org.apache.hadoop.hbase.master.balancer">BaseLoadBalancer.Cluster</a>&nbsp;cluster)</pre>
+<pre>protected&nbsp;int&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CandidateGenerator.html#line.685">pickRandomServer</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BaseLoadBalancer.Cluster.html" title="class in org.apache.hadoop.hbase.master.balancer">BaseLoadBalancer.Cluster</a>&nbsp;cluster)</pre>
 </li>
 </ul>
 <a name="pickRandomRack-org.apache.hadoop.hbase.master.balancer.BaseLoadBalancer.Cluster-">
@@ -291,7 +291,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>pickRandomRack</h4>
-<pre>protected&nbsp;int&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CandidateGenerator.html#line.691">pickRandomRack</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BaseLoadBalancer.Cluster.html" title="class in org.apache.hadoop.hbase.master.balancer">BaseLoadBalancer.Cluster</a>&nbsp;cluster)</pre>
+<pre>protected&nbsp;int&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CandidateGenerator.html#line.693">pickRandomRack</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BaseLoadBalancer.Cluster.html" title="class in org.apache.hadoop.hbase.master.balancer">BaseLoadBalancer.Cluster</a>&nbsp;cluster)</pre>
 </li>
 </ul>
 <a name="pickOtherRandomServer-org.apache.hadoop.hbase.master.balancer.BaseLoadBalancer.Cluster-int-">
@@ -300,7 +300,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>pickOtherRandomServer</h4>
-<pre>protected&nbsp;int&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CandidateGenerator.html#line.699">pickOtherRandomServer</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BaseLoadBalancer.Cluster.html" title="class in org.apache.hadoop.hbase.master.balancer">BaseLoadBalancer.Cluster</a>&nbsp;cluster,
+<pre>protected&nbsp;int&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CandidateGenerator.html#line.701">pickOtherRandomServer</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BaseLoadBalancer.Cluster.html" title="class in org.apache.hadoop.hbase.master.balancer">BaseLoadBalancer.Cluster</a>&nbsp;cluster,
                                     int&nbsp;serverIndex)</pre>
 </li>
 </ul>
@@ -310,7 +310,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>pickOtherRandomRack</h4>
-<pre>protected&nbsp;int&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CandidateGenerator.html#line.711">pickOtherRandomRack</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BaseLoadBalancer.Cluster.html" title="class in org.apache.hadoop.hbase.master.balancer">BaseLoadBalancer.Cluster</a>&nbsp;cluster,
+<pre>protected&nbsp;int&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CandidateGenerator.html#line.713">pickOtherRandomRack</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BaseLoadBalancer.Cluster.html" title="class in org.apache.hadoop.hbase.master.balancer">BaseLoadBalancer.Cluster</a>&nbsp;cluster,
                                   int&nbsp;rackIndex)</pre>
 </li>
 </ul>
@@ -320,7 +320,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>pickRandomRegions</h4>
-<pre>protected&nbsp;<a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BaseLoadBalancer.Cluster.Action.html" title="class in org.apache.hadoop.hbase.master.balancer">BaseLoadBalancer.Cluster.Action</a>&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CandidateGenerator.html#line.723">pickRandomRegions</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BaseLoadBalancer.Cluster.html" title="class in  [...]
+<pre>protected&nbsp;<a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BaseLoadBalancer.Cluster.Action.html" title="class in org.apache.hadoop.hbase.master.balancer">BaseLoadBalancer.Cluster.Action</a>&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CandidateGenerator.html#line.725">pickRandomRegions</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BaseLoadBalancer.Cluster.html" title="class in  [...]
                                                             int&nbsp;thisServer,
                                                             int&nbsp;otherServer)</pre>
 </li>
@@ -331,7 +331,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>getAction</h4>
-<pre>protected&nbsp;<a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BaseLoadBalancer.Cluster.Action.html" title="class in org.apache.hadoop.hbase.master.balancer">BaseLoadBalancer.Cluster.Action</a>&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CandidateGenerator.html#line.744">getAction</a>(int&nbsp;fromServer,
+<pre>protected&nbsp;<a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BaseLoadBalancer.Cluster.Action.html" title="class in org.apache.hadoop.hbase.master.balancer">BaseLoadBalancer.Cluster.Action</a>&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CandidateGenerator.html#line.746">getAction</a>(int&nbsp;fromServer,
                                                     int&nbsp;fromRegion,
                                                     int&nbsp;toServer,
                                                     int&nbsp;toRegion)</pre>
@@ -343,7 +343,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockListLast">
 <li class="blockList">
 <h4>getRandomIterationOrder</h4>
-<pre>protected&nbsp;<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="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;&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CandidateGenerator.html#line.764">getRandomIterationOrder</a>(int&nbsp;length)</pre>
+<pre>protected&nbsp;<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="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;&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CandidateGenerator.html#line.766">getRandomIterationOrder</a>(int&nbsp;length)</pre>
 <div class="block">Returns a random iteration order of indexes of an array with size length</div>
 </li>
 </ul>
diff --git a/devapidocs/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CostFromRegionLoadAsRateFunction.html b/devapidocs/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CostFromRegionLoadAsRateFunction.html
index 0a3c302..023feff 100644
--- a/devapidocs/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CostFromRegionLoadAsRateFunction.html
+++ b/devapidocs/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CostFromRegionLoadAsRateFunction.html
@@ -127,7 +127,7 @@ var activeTableTab = "activeTableTab";
 </dl>
 <hr>
 <br>
-<pre>abstract static class <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.html#line.1483">StochasticLoadBalancer.CostFromRegionLoadAsRateFunction</a>
+<pre>abstract static class <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.html#line.1485">StochasticLoadBalancer.CostFromRegionLoadAsRateFunction</a>
 extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CostFromRegionLoadFunction.html" title="class in org.apache.hadoop.hbase.master.balancer">StochasticLoadBalancer.CostFromRegionLoadFunction</a></pre>
 <div class="block">Class to be used for the subset of RegionLoad costs that should be treated as rates.
  We do not compare about the actual rate in requests per second but rather the rate relative
@@ -228,7 +228,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/Stoch
 <ul class="blockListLast">
 <li class="blockList">
 <h4>CostFromRegionLoadAsRateFunction</h4>
-<pre><a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CostFromRegionLoadAsRateFunction.html#line.1485">CostFromRegionLoadAsRateFunction</a>(org.apache.hadoop.conf.Configuration&nbsp;conf)</pre>
+<pre><a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CostFromRegionLoadAsRateFunction.html#line.1487">CostFromRegionLoadAsRateFunction</a>(org.apache.hadoop.conf.Configuration&nbsp;conf)</pre>
 </li>
 </ul>
 </li>
@@ -245,7 +245,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/Stoch
 <ul class="blockListLast">
 <li class="blockList">
 <h4>getRegionLoadCost</h4>
-<pre>protected&nbsp;double&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CostFromRegionLoadAsRateFunction.html#line.1490">getRegionLoadCost</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/master/balancer/BalancerRegionLoad.html" title="class in org.apache.hadoop.hbase.maste [...]
+<pre>protected&nbsp;double&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CostFromRegionLoadAsRateFunction.html#line.1492">getRegionLoadCost</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/master/balancer/BalancerRegionLoad.html" title="class in org.apache.hadoop.hbase.maste [...]
 <dl>
 <dt><span class="overrideSpecifyLabel">Overrides:</span></dt>
 <dd><code><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CostFromRegionLoadFunction.html#getRegionLoadCost-java.util.Collection-">getRegionLoadCost</a></code>&nbsp;in class&nbsp;<code><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CostFromRegionLoadFunction.html" title="class in org.apache.hadoop.hbase.master.balancer">StochasticLoadBalancer.CostFromRegionLoadFunction</a></code></dd>
diff --git a/devapidocs/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CostFromRegionLoadFunction.html b/devapidocs/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CostFromRegionLoadFunction.html
index 4e4ca77..a1aacdb 100644
--- a/devapidocs/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CostFromRegionLoadFunction.html
+++ b/devapidocs/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CostFromRegionLoadFunction.html
@@ -122,7 +122,7 @@ var activeTableTab = "activeTableTab";
 </dl>
 <hr>
 <br>
-<pre>abstract static class <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.html#line.1418">StochasticLoadBalancer.CostFromRegionLoadFunction</a>
+<pre>abstract static class <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.html#line.1420">StochasticLoadBalancer.CostFromRegionLoadFunction</a>
 extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CostFunction.html" title="class in org.apache.hadoop.hbase.master.balancer">StochasticLoadBalancer.CostFunction</a></pre>
 <div class="block">Base class the allows writing costs functions from rolling average of some
  number from RegionLoad.</div>
@@ -250,7 +250,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/Stoch
 <ul class="blockList">
 <li class="blockList">
 <h4>clusterStatus</h4>
-<pre>private&nbsp;<a href="../../../../../../org/apache/hadoop/hbase/ClusterMetrics.html" title="interface in org.apache.hadoop.hbase">ClusterMetrics</a> <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CostFromRegionLoadFunction.html#line.1420">clusterStatus</a></pre>
+<pre>private&nbsp;<a href="../../../../../../org/apache/hadoop/hbase/ClusterMetrics.html" title="interface in org.apache.hadoop.hbase">ClusterMetrics</a> <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CostFromRegionLoadFunction.html#line.1422">clusterStatus</a></pre>
 </li>
 </ul>
 <a name="loads">
@@ -259,7 +259,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/Stoch
 <ul class="blockList">
 <li class="blockList">
 <h4>loads</h4>
-<pre>private&nbsp;<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/hbase [...]
+<pre>private&nbsp;<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/hbase [...]
 </li>
 </ul>
 <a name="stats">
@@ -268,7 +268,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/Stoch
 <ul class="blockListLast">
 <li class="blockList">
 <h4>stats</h4>
-<pre>private&nbsp;double[] <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CostFromRegionLoadFunction.html#line.1422">stats</a></pre>
+<pre>private&nbsp;double[] <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CostFromRegionLoadFunction.html#line.1424">stats</a></pre>
 </li>
 </ul>
 </li>
@@ -285,7 +285,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/Stoch
 <ul class="blockListLast">
 <li class="blockList">
 <h4>CostFromRegionLoadFunction</h4>
-<pre><a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CostFromRegionLoadFunction.html#line.1423">CostFromRegionLoadFunction</a>(org.apache.hadoop.conf.Configuration&nbsp;conf)</pre>
+<pre><a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CostFromRegionLoadFunction.html#line.1425">CostFromRegionLoadFunction</a>(org.apache.hadoop.conf.Configuration&nbsp;conf)</pre>
 </li>
 </ul>
 </li>
@@ -302,7 +302,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/Stoch
 <ul class="blockList">
 <li class="blockList">
 <h4>setClusterMetrics</h4>
-<pre>void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CostFromRegionLoadFunction.html#line.1427">setClusterMetrics</a>(<a href="../../../../../../org/apache/hadoop/hbase/ClusterMetrics.html" title="interface in org.apache.hadoop.hbase">ClusterMetrics</a>&nbsp;status)</pre>
+<pre>void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CostFromRegionLoadFunction.html#line.1429">setClusterMetrics</a>(<a href="../../../../../../org/apache/hadoop/hbase/ClusterMetrics.html" title="interface in org.apache.hadoop.hbase">ClusterMetrics</a>&nbsp;status)</pre>
 </li>
 </ul>
 <a name="setLoads-java.util.Map-">
@@ -311,7 +311,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/Stoch
 <ul class="blockList">
 <li class="blockList">
 <h4>setLoads</h4>
-<pre>void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CostFromRegionLoadFunction.html#line.1431">setLoads</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="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 [...]
+<pre>void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CostFromRegionLoadFunction.html#line.1433">setLoads</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="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 [...]
 </li>
 </ul>
 <a name="cost--">
@@ -320,7 +320,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/Stoch
 <ul class="blockList">
 <li class="blockList">
 <h4>cost</h4>
-<pre>protected&nbsp;double&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CostFromRegionLoadFunction.html#line.1436">cost</a>()</pre>
+<pre>protected&nbsp;double&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CostFromRegionLoadFunction.html#line.1438">cost</a>()</pre>
 <dl>
 <dt><span class="overrideSpecifyLabel">Specified by:</span></dt>
 <dd><code><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CostFunction.html#cost--">cost</a></code>&nbsp;in class&nbsp;<code><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CostFunction.html" title="class in org.apache.hadoop.hbase.master.balancer">StochasticLoadBalancer.CostFunction</a></code></dd>
@@ -333,7 +333,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/Stoch
 <ul class="blockList">
 <li class="blockList">
 <h4>getRegionLoadCost</h4>
-<pre>protected&nbsp;double&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CostFromRegionLoadFunction.html#line.1467">getRegionLoadCost</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/master/balancer/BalancerRegionLoad.html" title="class in org.apache.hadoop.hbase.master.bala [...]
+<pre>protected&nbsp;double&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CostFromRegionLoadFunction.html#line.1469">getRegionLoadCost</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/master/balancer/BalancerRegionLoad.html" title="class in org.apache.hadoop.hbase.master.bala [...]
 </li>
 </ul>
 <a name="getCostFromRl-org.apache.hadoop.hbase.master.balancer.BalancerRegionLoad-">
@@ -342,7 +342,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/Stoch
 <ul class="blockListLast">
 <li class="blockList">
 <h4>getCostFromRl</h4>
-<pre>protected abstract&nbsp;double&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CostFromRegionLoadFunction.html#line.1475">getCostFromRl</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BalancerRegionLoad.html" title="class in org.apache.hadoop.hbase.master.balancer">BalancerRegionLoad</a>&nbsp;rl)</pre>
+<pre>protected abstract&nbsp;double&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CostFromRegionLoadFunction.html#line.1477">getCostFromRl</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BalancerRegionLoad.html" title="class in org.apache.hadoop.hbase.master.balancer">BalancerRegionLoad</a>&nbsp;rl)</pre>
 </li>
 </ul>
 </li>
diff --git a/devapidocs/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CostFunction.html b/devapidocs/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CostFunction.html
index 043b87d..e66bec3 100644
--- a/devapidocs/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CostFunction.html
+++ b/devapidocs/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CostFunction.html
@@ -117,7 +117,7 @@ var activeTableTab = "activeTableTab";
 </dl>
 <hr>
 <br>
-<pre>public abstract static class <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.html#line.1019">StochasticLoadBalancer.CostFunction</a>
+<pre>public abstract static class <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.html#line.1021">StochasticLoadBalancer.CostFunction</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">Base class of StochasticLoadBalancer's Cost Functions.</div>
 </li>
@@ -258,7 +258,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>multiplier</h4>
-<pre>private&nbsp;float <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CostFunction.html#line.1021">multiplier</a></pre>
+<pre>private&nbsp;float <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CostFunction.html#line.1023">multiplier</a></pre>
 </li>
 </ul>
 <a name="cluster">
@@ -267,7 +267,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockListLast">
 <li class="blockList">
 <h4>cluster</h4>
-<pre>protected&nbsp;<a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BaseLoadBalancer.Cluster.html" title="class in org.apache.hadoop.hbase.master.balancer">BaseLoadBalancer.Cluster</a> <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CostFunction.html#line.1023">cluster</a></pre>
+<pre>protected&nbsp;<a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BaseLoadBalancer.Cluster.html" title="class in org.apache.hadoop.hbase.master.balancer">BaseLoadBalancer.Cluster</a> <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CostFunction.html#line.1025">cluster</a></pre>
 </li>
 </ul>
 </li>
@@ -284,7 +284,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockListLast">
 <li class="blockList">
 <h4>CostFunction</h4>
-<pre>public&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CostFunction.html#line.1025">CostFunction</a>(org.apache.hadoop.conf.Configuration&nbsp;c)</pre>
+<pre>public&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CostFunction.html#line.1027">CostFunction</a>(org.apache.hadoop.conf.Configuration&nbsp;c)</pre>
 </li>
 </ul>
 </li>
@@ -301,7 +301,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>isNeeded</h4>
-<pre>boolean&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CostFunction.html#line.1028">isNeeded</a>()</pre>
+<pre>boolean&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CostFunction.html#line.1030">isNeeded</a>()</pre>
 </li>
 </ul>
 <a name="getMultiplier--">
@@ -310,7 +310,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>getMultiplier</h4>
-<pre>float&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CostFunction.html#line.1031">getMultiplier</a>()</pre>
+<pre>float&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CostFunction.html#line.1033">getMultiplier</a>()</pre>
 </li>
 </ul>
 <a name="setMultiplier-float-">
@@ -319,7 +319,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>setMultiplier</h4>
-<pre>void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CostFunction.html#line.1035">setMultiplier</a>(float&nbsp;m)</pre>
+<pre>void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CostFunction.html#line.1037">setMultiplier</a>(float&nbsp;m)</pre>
 </li>
 </ul>
 <a name="init-org.apache.hadoop.hbase.master.balancer.BaseLoadBalancer.Cluster-">
@@ -328,7 +328,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>init</h4>
-<pre>void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CostFunction.html#line.1042">init</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BaseLoadBalancer.Cluster.html" title="class in org.apache.hadoop.hbase.master.balancer">BaseLoadBalancer.Cluster</a>&nbsp;cluster)</pre>
+<pre>void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CostFunction.html#line.1044">init</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BaseLoadBalancer.Cluster.html" title="class in org.apache.hadoop.hbase.master.balancer">BaseLoadBalancer.Cluster</a>&nbsp;cluster)</pre>
 <div class="block">Called once per LB invocation to give the cost function
  to initialize it's state, and perform any costly calculation.</div>
 </li>
@@ -339,7 +339,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>postAction</h4>
-<pre>void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CostFunction.html#line.1050">postAction</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BaseLoadBalancer.Cluster.Action.html" title="class in org.apache.hadoop.hbase.master.balancer">BaseLoadBalancer.Cluster.Action</a>&nbsp;action)</pre>
+<pre>void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CostFunction.html#line.1052">postAction</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BaseLoadBalancer.Cluster.Action.html" title="class in org.apache.hadoop.hbase.master.balancer">BaseLoadBalancer.Cluster.Action</a>&nbsp;action)</pre>
 <div class="block">Called once per cluster Action to give the cost function
  an opportunity to update it's state. postAction() is always
  called at least once before cost() is called with the cluster
@@ -352,7 +352,7 @@ 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>protected&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CostFunction.html#line.1071">regionMoved</a>(int&nbsp;region,
+<pre>protected&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CostFunction.html#line.1073">regionMoved</a>(int&nbsp;region,
                            int&nbsp;oldServer,
                            int&nbsp;newServer)</pre>
 </li>
@@ -363,7 +363,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>cost</h4>
-<pre>protected abstract&nbsp;double&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CostFunction.html#line.1074">cost</a>()</pre>
+<pre>protected abstract&nbsp;double&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CostFunction.html#line.1076">cost</a>()</pre>
 </li>
 </ul>
 <a name="costFromArray-double:A-">
@@ -372,7 +372,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>costFromArray</h4>
-<pre>protected&nbsp;double&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CostFunction.html#line.1086">costFromArray</a>(double[]&nbsp;stats)</pre>
+<pre>protected&nbsp;double&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CostFunction.html#line.1088">costFromArray</a>(double[]&nbsp;stats)</pre>
 </li>
 </ul>
 <a name="getSum-double:A-">
@@ -381,7 +381,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>getSum</h4>
-<pre>private&nbsp;double&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CostFunction.html#line.1120">getSum</a>(double[]&nbsp;stats)</pre>
+<pre>private&nbsp;double&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CostFunction.html#line.1122">getSum</a>(double[]&nbsp;stats)</pre>
 </li>
 </ul>
 <a name="scale-double-double-double-">
@@ -390,7 +390,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockListLast">
 <li class="blockList">
 <h4>scale</h4>
-<pre>protected&nbsp;double&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CostFunction.html#line.1136">scale</a>(double&nbsp;min,
+<pre>protected&nbsp;double&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CostFunction.html#line.1138">scale</a>(double&nbsp;min,
                        double&nbsp;max,
                        double&nbsp;value)</pre>
 <div class="block">Scale the value between 0 and 1.</div>
diff --git a/devapidocs/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.LoadCandidateGenerator.html b/devapidocs/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.LoadCandidateGenerator.html
index 6435e32..21bc13f 100644
--- a/devapidocs/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.LoadCandidateGenerator.html
+++ b/devapidocs/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.LoadCandidateGenerator.html
@@ -118,7 +118,7 @@ var activeTableTab = "activeTableTab";
 </dl>
 <hr>
 <br>
-<pre>static class <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.html#line.788">StochasticLoadBalancer.LoadCandidateGenerator</a>
+<pre>static class <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.html#line.790">StochasticLoadBalancer.LoadCandidateGenerator</a>
 extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CandidateGenerator.html" title="class in org.apache.hadoop.hbase.master.balancer">StochasticLoadBalancer.CandidateGenerator</a></pre>
 </li>
 </ul>
@@ -204,7 +204,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/Stoch
 <ul class="blockListLast">
 <li class="blockList">
 <h4>LoadCandidateGenerator</h4>
-<pre><a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.LoadCandidateGenerator.html#line.788">LoadCandidateGenerator</a>()</pre>
+<pre><a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.LoadCandidateGenerator.html#line.790">LoadCandidateGenerator</a>()</pre>
 </li>
 </ul>
 </li>
@@ -221,7 +221,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/Stoch
 <ul class="blockList">
 <li class="blockList">
 <h4>generate</h4>
-<pre><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BaseLoadBalancer.Cluster.Action.html" title="class in org.apache.hadoop.hbase.master.balancer">BaseLoadBalancer.Cluster.Action</a>&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.LoadCandidateGenerator.html#line.791">generate</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BaseLoadBalancer.Cluster.html" title="class in org.apache.hadoop.hb [...]
+<pre><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BaseLoadBalancer.Cluster.Action.html" title="class in org.apache.hadoop.hbase.master.balancer">BaseLoadBalancer.Cluster.Action</a>&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.LoadCandidateGenerator.html#line.793">generate</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BaseLoadBalancer.Cluster.html" title="class in org.apache.hadoop.hb [...]
 <dl>
 <dt><span class="overrideSpecifyLabel">Specified by:</span></dt>
 <dd><code><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CandidateGenerator.html#generate-org.apache.hadoop.hbase.master.balancer.BaseLoadBalancer.Cluster-">generate</a></code>&nbsp;in class&nbsp;<code><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CandidateGenerator.html" title="class in org.apache.hadoop.hbase.master.balancer">StochasticLoadBalancer.CandidateGenerator</a></code></dd>
@@ -234,7 +234,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/Stoch
 <ul class="blockList">
 <li class="blockList">
 <h4>pickLeastLoadedServer</h4>
-<pre>private&nbsp;int&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.LoadCandidateGenerator.html#line.799">pickLeastLoadedServer</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BaseLoadBalancer.Cluster.html" title="class in org.apache.hadoop.hbase.master.balancer">BaseLoadBalancer.Cluster</a>&nbsp;cluster,
+<pre>private&nbsp;int&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.LoadCandidateGenerator.html#line.801">pickLeastLoadedServer</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BaseLoadBalancer.Cluster.html" title="class in org.apache.hadoop.hbase.master.balancer">BaseLoadBalancer.Cluster</a>&nbsp;cluster,
                                   int&nbsp;thisServer)</pre>
 </li>
 </ul>
@@ -244,7 +244,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/Stoch
 <ul class="blockListLast">
 <li class="blockList">
 <h4>pickMostLoadedServer</h4>
-<pre>private&nbsp;int&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.LoadCandidateGenerator.html#line.812">pickMostLoadedServer</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BaseLoadBalancer.Cluster.html" title="class in org.apache.hadoop.hbase.master.balancer">BaseLoadBalancer.Cluster</a>&nbsp;cluster,
+<pre>private&nbsp;int&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.LoadCandidateGenerator.html#line.814">pickMostLoadedServer</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BaseLoadBalancer.Cluster.html" title="class in org.apache.hadoop.hbase.master.balancer">BaseLoadBalancer.Cluster</a>&nbsp;cluster,
                                  int&nbsp;thisServer)</pre>
 </li>
 </ul>
diff --git a/devapidocs/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.LocalityBasedCandidateGenerator.html b/devapidocs/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.LocalityBasedCandidateGenerator.html
index e156e89..bacbac4 100644
--- a/devapidocs/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.LocalityBasedCandidateGenerator.html
+++ b/devapidocs/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.LocalityBasedCandidateGenerator.html
@@ -118,7 +118,7 @@ var activeTableTab = "activeTableTab";
 </dl>
 <hr>
 <br>
-<pre>static class <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.html#line.826">StochasticLoadBalancer.LocalityBasedCandidateGenerator</a>
+<pre>static class <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.html#line.828">StochasticLoadBalancer.LocalityBasedCandidateGenerator</a>
 extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CandidateGenerator.html" title="class in org.apache.hadoop.hbase.master.balancer">StochasticLoadBalancer.CandidateGenerator</a></pre>
 </li>
 </ul>
@@ -232,7 +232,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/Stoch
 <ul class="blockListLast">
 <li class="blockList">
 <h4>masterServices</h4>
-<pre>private&nbsp;<a href="../../../../../../org/apache/hadoop/hbase/master/MasterServices.html" title="interface in org.apache.hadoop.hbase.master">MasterServices</a> <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.LocalityBasedCandidateGenerator.html#line.828">masterServices</a></pre>
+<pre>private&nbsp;<a href="../../../../../../org/apache/hadoop/hbase/master/MasterServices.html" title="interface in org.apache.hadoop.hbase.master">MasterServices</a> <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.LocalityBasedCandidateGenerator.html#line.830">masterServices</a></pre>
 </li>
 </ul>
 </li>
@@ -249,7 +249,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/Stoch
 <ul class="blockListLast">
 <li class="blockList">
 <h4>LocalityBasedCandidateGenerator</h4>
-<pre><a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.LocalityBasedCandidateGenerator.html#line.830">LocalityBasedCandidateGenerator</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/MasterServices.html" title="interface in org.apache.hadoop.hbase.master">MasterServices</a>&nbsp;masterServices)</pre>
+<pre><a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.LocalityBasedCandidateGenerator.html#line.832">LocalityBasedCandidateGenerator</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/MasterServices.html" title="interface in org.apache.hadoop.hbase.master">MasterServices</a>&nbsp;masterServices)</pre>
 </li>
 </ul>
 </li>
@@ -266,7 +266,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/Stoch
 <ul class="blockList">
 <li class="blockList">
 <h4>generate</h4>
-<pre><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BaseLoadBalancer.Cluster.Action.html" title="class in org.apache.hadoop.hbase.master.balancer">BaseLoadBalancer.Cluster.Action</a>&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.LocalityBasedCandidateGenerator.html#line.835">generate</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BaseLoadBalancer.Cluster.html" title="class in org.apache. [...]
+<pre><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BaseLoadBalancer.Cluster.Action.html" title="class in org.apache.hadoop.hbase.master.balancer">BaseLoadBalancer.Cluster.Action</a>&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.LocalityBasedCandidateGenerator.html#line.837">generate</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BaseLoadBalancer.Cluster.html" title="class in org.apache. [...]
 <dl>
 <dt><span class="overrideSpecifyLabel">Specified by:</span></dt>
 <dd><code><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CandidateGenerator.html#generate-org.apache.hadoop.hbase.master.balancer.BaseLoadBalancer.Cluster-">generate</a></code>&nbsp;in class&nbsp;<code><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CandidateGenerator.html" title="class in org.apache.hadoop.hbase.master.balancer">StochasticLoadBalancer.CandidateGenerator</a></code></dd>
@@ -279,7 +279,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/Stoch
 <ul class="blockList">
 <li class="blockList">
 <h4>tryMoveOrSwap</h4>
-<pre>private&nbsp;org.apache.hbase.thirdparty.com.google.common.base.Optional&lt;<a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BaseLoadBalancer.Cluster.Action.html" title="class in org.apache.hadoop.hbase.master.balancer">BaseLoadBalancer.Cluster.Action</a>&gt;&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.LocalityBasedCandidateGenerator.html#line.865">tryMoveOrSwap</a>(<a href="../../../../../../org/apache/ha [...]
+<pre>private&nbsp;org.apache.hbase.thirdparty.com.google.common.base.Optional&lt;<a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BaseLoadBalancer.Cluster.Action.html" title="class in org.apache.hadoop.hbase.master.balancer">BaseLoadBalancer.Cluster.Action</a>&gt;&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.LocalityBasedCandidateGenerator.html#line.867">tryMoveOrSwap</a>(<a href="../../../../../../org/apache/ha [...]
                                                                                                                    int&nbsp;fromServer,
                                                                                                                    int&nbsp;fromRegion,
                                                                                                                    int&nbsp;toServer)</pre>
@@ -293,7 +293,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/Stoch
 <ul class="blockList">
 <li class="blockList">
 <h4>getWeightedLocality</h4>
-<pre>private&nbsp;double&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.LocalityBasedCandidateGenerator.html#line.890">getWeightedLocality</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BaseLoadBalancer.Cluster.html" title="class in org.apache.hadoop.hbase.master.balancer">BaseLoadBalancer.Cluster</a>&nbsp;cluster,
+<pre>private&nbsp;double&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.LocalityBasedCandidateGenerator.html#line.892">getWeightedLocality</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BaseLoadBalancer.Cluster.html" title="class in org.apache.hadoop.hbase.master.balancer">BaseLoadBalancer.Cluster</a>&nbsp;cluster,
                                    int&nbsp;region,
                                    int&nbsp;server)</pre>
 </li>
@@ -304,7 +304,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/Stoch
 <ul class="blockListLast">
 <li class="blockList">
 <h4>setServices</h4>
-<pre>void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.LocalityBasedCandidateGenerator.html#line.894">setServices</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/MasterServices.html" title="interface in org.apache.hadoop.hbase.master">MasterServices</a>&nbsp;services)</pre>
+<pre>void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.LocalityBasedCandidateGenerator.html#line.896">setServices</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/MasterServices.html" title="interface in org.apache.hadoop.hbase.master">MasterServices</a>&nbsp;services)</pre>
 </li>
 </ul>
 </li>
diff --git a/devapidocs/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.LocalityBasedCostFunction.html b/devapidocs/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.LocalityBasedCostFunction.html
index dcd4866..0a99a96 100644
--- a/devapidocs/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.LocalityBasedCostFunction.html
+++ b/devapidocs/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.LocalityBasedCostFunction.html
@@ -122,7 +122,7 @@ var activeTableTab = "activeTableTab";
 </dl>
 <hr>
 <br>
-<pre>abstract static class <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.html#line.1292">StochasticLoadBalancer.LocalityBasedCostFunction</a>
+<pre>abstract static class <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.html#line.1294">StochasticLoadBalancer.LocalityBasedCostFunction</a>
 extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CostFunction.html" title="class in org.apache.hadoop.hbase.master.balancer">StochasticLoadBalancer.CostFunction</a></pre>
 <div class="block">Compute a cost of a potential cluster configuration based upon where
  <a href="../../../../../../org/apache/hadoop/hbase/regionserver/HStoreFile.html" title="class in org.apache.hadoop.hbase.regionserver"><code>HStoreFile</code></a>s are located.</div>
@@ -274,7 +274,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/Stoch
 <ul class="blockList">
 <li class="blockList">
 <h4>type</h4>
-<pre>private final&nbsp;<a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BaseLoadBalancer.Cluster.LocalityType.html" title="enum in org.apache.hadoop.hbase.master.balancer">BaseLoadBalancer.Cluster.LocalityType</a> <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.LocalityBasedCostFunction.html#line.1294">type</a></pre>
+<pre>private final&nbsp;<a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BaseLoadBalancer.Cluster.LocalityType.html" title="enum in org.apache.hadoop.hbase.master.balancer">BaseLoadBalancer.Cluster.LocalityType</a> <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.LocalityBasedCostFunction.html#line.1296">type</a></pre>
 </li>
 </ul>
 <a name="bestLocality">
@@ -283,7 +283,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/Stoch
 <ul class="blockList">
 <li class="blockList">
 <h4>bestLocality</h4>
-<pre>private&nbsp;double <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.LocalityBasedCostFunction.html#line.1296">bestLocality</a></pre>
+<pre>private&nbsp;double <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.LocalityBasedCostFunction.html#line.1298">bestLocality</a></pre>
 </li>
 </ul>
 <a name="locality">
@@ -292,7 +292,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/Stoch
 <ul class="blockList">
 <li class="blockList">
 <h4>locality</h4>
-<pre>private&nbsp;double <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.LocalityBasedCostFunction.html#line.1297">locality</a></pre>
+<pre>private&nbsp;double <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.LocalityBasedCostFunction.html#line.1299">locality</a></pre>
 </li>
 </ul>
 <a name="services">
@@ -301,7 +301,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/Stoch
 <ul class="blockListLast">
 <li class="blockList">
 <h4>services</h4>
-<pre>private&nbsp;<a href="../../../../../../org/apache/hadoop/hbase/master/MasterServices.html" title="interface in org.apache.hadoop.hbase.master">MasterServices</a> <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.LocalityBasedCostFunction.html#line.1299">services</a></pre>
+<pre>private&nbsp;<a href="../../../../../../org/apache/hadoop/hbase/master/MasterServices.html" title="interface in org.apache.hadoop.hbase.master">MasterServices</a> <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.LocalityBasedCostFunction.html#line.1301">services</a></pre>
 </li>
 </ul>
 </li>
@@ -318,7 +318,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/Stoch
 <ul class="blockListLast">
 <li class="blockList">
 <h4>LocalityBasedCostFunction</h4>
-<pre><a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.LocalityBasedCostFunction.html#line.1301">LocalityBasedCostFunction</a>(org.apache.hadoop.conf.Configuration&nbsp;conf,
+<pre><a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.LocalityBasedCostFunction.html#line.1303">LocalityBasedCostFunction</a>(org.apache.hadoop.conf.Configuration&nbsp;conf,
                           <a href="../../../../../../org/apache/hadoop/hbase/master/MasterServices.html" title="interface in org.apache.hadoop.hbase.master">MasterServices</a>&nbsp;srv,
                           <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BaseLoadBalancer.Cluster.LocalityType.html" title="enum in org.apache.hadoop.hbase.master.balancer">BaseLoadBalancer.Cluster.LocalityType</a>&nbsp;type,
                           <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;localityCostKey,
@@ -339,7 +339,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/Stoch
 <ul class="blockList">
 <li class="blockList">
 <h4>regionIndexToEntityIndex</h4>
-<pre>abstract&nbsp;int&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.LocalityBasedCostFunction.html#line.1317">regionIndexToEntityIndex</a>(int&nbsp;region)</pre>
+<pre>abstract&nbsp;int&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.LocalityBasedCostFunction.html#line.1319">regionIndexToEntityIndex</a>(int&nbsp;region)</pre>
 <div class="block">Maps region to the current entity (server or rack) on which it is stored</div>
 </li>
 </ul>
@@ -349,7 +349,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/Stoch
 <ul class="blockList">
 <li class="blockList">
 <h4>setServices</h4>
-<pre>public&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.LocalityBasedCostFunction.html#line.1319">setServices</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/MasterServices.html" title="interface in org.apache.hadoop.hbase.master">MasterServices</a>&nbsp;srvc)</pre>
+<pre>public&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.LocalityBasedCostFunction.html#line.1321">setServices</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/MasterServices.html" title="interface in org.apache.hadoop.hbase.master">MasterServices</a>&nbsp;srvc)</pre>
 </li>
 </ul>
 <a name="init-org.apache.hadoop.hbase.master.balancer.BaseLoadBalancer.Cluster-">
@@ -358,7 +358,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/Stoch
 <ul class="blockList">
 <li class="blockList">
 <h4>init</h4>
-<pre>void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.LocalityBasedCostFunction.html#line.1324">init</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BaseLoadBalancer.Cluster.html" title="class in org.apache.hadoop.hbase.master.balancer">BaseLoadBalancer.Cluster</a>&nbsp;cluster)</pre>
+<pre>void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.LocalityBasedCostFunction.html#line.1326">init</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BaseLoadBalancer.Cluster.html" title="class in org.apache.hadoop.hbase.master.balancer">BaseLoadBalancer.Cluster</a>&nbsp;cluster)</pre>
 <div class="block"><span class="descfrmTypeLabel">Description copied from class:&nbsp;<code><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CostFunction.html#init-org.apache.hadoop.hbase.master.balancer.BaseLoadBalancer.Cluster-">StochasticLoadBalancer.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>
@@ -374,7 +374,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/Stoch
 <ul class="blockList">
 <li class="blockList">
 <h4>regionMoved</h4>
-<pre>protected&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.LocalityBasedCostFunction.html#line.1346">regionMoved</a>(int&nbsp;region,
+<pre>protected&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.LocalityBasedCostFunction.html#line.1348">regionMoved</a>(int&nbsp;region,
                            int&nbsp;oldServer,
                            int&nbsp;newServer)</pre>
 <dl>
@@ -389,7 +389,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/Stoch
 <ul class="blockList">
 <li class="blockList">
 <h4>cost</h4>
-<pre>protected&nbsp;double&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.LocalityBasedCostFunction.html#line.1358">cost</a>()</pre>
+<pre>protected&nbsp;double&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.LocalityBasedCostFunction.html#line.1360">cost</a>()</pre>
 <dl>
 <dt><span class="overrideSpecifyLabel">Specified by:</span></dt>
 <dd><code><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CostFunction.html#cost--">cost</a></code>&nbsp;in class&nbsp;<code><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CostFunction.html" title="class in org.apache.hadoop.hbase.master.balancer">StochasticLoadBalancer.CostFunction</a></code></dd>
@@ -402,7 +402,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/Stoch
 <ul class="blockList">
 <li class="blockList">
 <h4>getMostLocalEntityForRegion</h4>
-<pre>private&nbsp;int&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.LocalityBasedCostFunction.html#line.1362">getMostLocalEntityForRegion</a>(int&nbsp;region)</pre>
+<pre>private&nbsp;int&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.LocalityBasedCostFunction.html#line.1364">getMostLocalEntityForRegion</a>(int&nbsp;region)</pre>
 </li>
 </ul>
 <a name="getWeightedLocality-int-int-">
@@ -411,7 +411,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/Stoch
 <ul class="blockListLast">
 <li class="blockList">
 <h4>getWeightedLocality</h4>
-<pre>private&nbsp;double&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.LocalityBasedCostFunction.html#line.1366">getWeightedLocality</a>(int&nbsp;region,
+<pre>private&nbsp;double&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.LocalityBasedCostFunction.html#line.1368">getWeightedLocality</a>(int&nbsp;region,
                                    int&nbsp;entity)</pre>
 </li>
 </ul>
diff --git a/devapidocs/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.MemStoreSizeCostFunction.html b/devapidocs/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.MemStoreSizeCostFunction.html
index 0d8b511..dfba314 100644
--- a/devapidocs/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.MemStoreSizeCostFunction.html
+++ b/devapidocs/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.MemStoreSizeCostFunction.html
@@ -128,7 +128,7 @@ var activeTableTab = "activeTableTab";
 </dl>
 <hr>
 <br>
-<pre>static class <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.html#line.1738">StochasticLoadBalancer.MemStoreSizeCostFunction</a>
+<pre>static class <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.html#line.1740">StochasticLoadBalancer.MemStoreSizeCostFunction</a>
 extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CostFromRegionLoadAsRateFunction.html" title="class in org.apache.hadoop.hbase.master.balancer">StochasticLoadBalancer.CostFromRegionLoadAsRateFunction</a></pre>
 <div class="block">Compute the cost of total memstore size.  The more unbalanced the higher the
  computed cost will be.  This uses a rolling average of regionload.</div>
@@ -250,7 +250,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/Stoch
 <ul class="blockList">
 <li class="blockList">
 <h4>MEMSTORE_SIZE_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/StochasticLoadBalancer.MemStoreSizeCostFunction.html#line.1740">MEMSTORE_SIZE_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/StochasticLoadBalancer.MemStoreSizeCostFunction.html#line.1742">MEMSTORE_SIZE_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.StochasticLoadBalancer.MemStoreSizeCostFunction.MEMSTORE_SIZE_COST_KEY">Constant Field Values</a></dd>
@@ -263,7 +263,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/Stoch
 <ul class="blockListLast">
 <li class="blockList">
 <h4>DEFAULT_MEMSTORE_SIZE_COST</h4>
-<pre>private static final&nbsp;float <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.MemStoreSizeCostFunction.html#line.1742">DEFAULT_MEMSTORE_SIZE_COST</a></pre>
+<pre>private static final&nbsp;float <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.MemStoreSizeCostFunction.html#line.1744">DEFAULT_MEMSTORE_SIZE_COST</a></pre>
 <dl>
 <dt><span class="seeLabel">See Also:</span></dt>
 <dd><a href="../../../../../../constant-values.html#org.apache.hadoop.hbase.master.balancer.StochasticLoadBalancer.MemStoreSizeCostFunction.DEFAULT_MEMSTORE_SIZE_COST">Constant Field Values</a></dd>
@@ -284,7 +284,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/Stoch
 <ul class="blockListLast">
 <li class="blockList">
 <h4>MemStoreSizeCostFunction</h4>
-<pre><a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.MemStoreSizeCostFunction.html#line.1744">MemStoreSizeCostFunction</a>(org.apache.hadoop.conf.Configuration&nbsp;conf)</pre>
+<pre><a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.MemStoreSizeCostFunction.html#line.1746">MemStoreSizeCostFunction</a>(org.apache.hadoop.conf.Configuration&nbsp;conf)</pre>
 </li>
 </ul>
 </li>
@@ -301,7 +301,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/Stoch
 <ul class="blockListLast">
 <li class="blockList">
 <h4>getCostFromRl</h4>
-<pre>protected&nbsp;double&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.MemStoreSizeCostFunction.html#line.1750">getCostFromRl</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BalancerRegionLoad.html" title="class in org.apache.hadoop.hbase.master.balancer">BalancerRegionLoad</a>&nbsp;rl)</pre>
+<pre>protected&nbsp;double&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.MemStoreSizeCostFunction.html#line.1752">getCostFromRl</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BalancerRegionLoad.html" title="class in org.apache.hadoop.hbase.master.balancer">BalancerRegionLoad</a>&nbsp;rl)</pre>
 <dl>
 <dt><span class="overrideSpecifyLabel">Specified by:</span></dt>
 <dd><code><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CostFromRegionLoadFunction.html#getCostFromRl-org.apache.hadoop.hbase.master.balancer.BalancerRegionLoad-">getCostFromRl</a></code>&nbsp;in class&nbsp;<code><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CostFromRegionLoadFunction.html" title="class in org.apache.hadoop.hbase.master.balancer">StochasticLoadBalancer.CostFromRegionLoadFunction</a></ [...]
diff --git a/devapidocs/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.MoveCostFunction.html b/devapidocs/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.MoveCostFunction.html
index d9a2d00..eec65e7 100644
--- a/devapidocs/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.MoveCostFunction.html
+++ b/devapidocs/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.MoveCostFunction.html
@@ -118,7 +118,7 @@ var activeTableTab = "activeTableTab";
 </dl>
 <hr>
 <br>
-<pre>static class <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.html#line.1150">StochasticLoadBalancer.MoveCostFunction</a>
+<pre>static class <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.html#line.1152">StochasticLoadBalancer.MoveCostFunction</a>
 extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CostFunction.html" title="class in org.apache.hadoop.hbase.master.balancer">StochasticLoadBalancer.CostFunction</a></pre>
 <div class="block">Given the starting state of the regions and a potential ending state
  compute cost based upon the number of regions that have moved.</div>
@@ -242,7 +242,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/Stoch
 <ul class="blockList">
 <li class="blockList">
 <h4>MOVE_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/StochasticLoadBalancer.MoveCostFunction.html#line.1151">MOVE_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/StochasticLoadBalancer.MoveCostFunction.html#line.1153">MOVE_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.StochasticLoadBalancer.MoveCostFunction.MOVE_COST_KEY">Constant Field Values</a></dd>
@@ -255,7 +255,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/Stoch
 <ul class="blockList">
 <li class="blockList">
 <h4>MAX_MOVES_PERCENT_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/StochasticLoadBalancer.MoveCostFunction.html#line.1152">MAX_MOVES_PERCENT_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/StochasticLoadBalancer.MoveCostFunction.html#line.1154">MAX_MOVES_PERCENT_KEY</a></pre>
 <dl>
 <dt><span class="seeLabel">See Also:</span></dt>
 <dd><a href="../../../../../../constant-values.html#org.apache.hadoop.hbase.master.balancer.StochasticLoadBalancer.MoveCostFunction.MAX_MOVES_PERCENT_KEY">Constant Field Values</a></dd>
@@ -268,7 +268,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/Stoch
 <ul class="blockList">
 <li class="blockList">
 <h4>DEFAULT_MOVE_COST</h4>
-<pre>private static final&nbsp;float <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.MoveCostFunction.html#line.1154">DEFAULT_MOVE_COST</a></pre>
+<pre>private static final&nbsp;float <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.MoveCostFunction.html#line.1156">DEFAULT_MOVE_COST</a></pre>
 <dl>
 <dt><span class="seeLabel">See Also:</span></dt>
 <dd><a href="../../../../../../constant-values.html#org.apache.hadoop.hbase.master.balancer.StochasticLoadBalancer.MoveCostFunction.DEFAULT_MOVE_COST">Constant Field Values</a></dd>
@@ -281,7 +281,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/Stoch
 <ul class="blockList">
 <li class="blockList">
 <h4>DEFAULT_MAX_MOVES</h4>
-<pre>private static final&nbsp;int <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.MoveCostFunction.html#line.1155">DEFAULT_MAX_MOVES</a></pre>
+<pre>private static final&nbsp;int <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.MoveCostFunction.html#line.1157">DEFAULT_MAX_MOVES</a></pre>
 <dl>
 <dt><span class="seeLabel">See Also:</span></dt>
 <dd><a href="../../../../../../constant-values.html#org.apache.hadoop.hbase.master.balancer.StochasticLoadBalancer.MoveCostFunction.DEFAULT_MAX_MOVES">Constant Field Values</a></dd>
@@ -294,7 +294,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/Stoch
 <ul class="blockList">
 <li class="blockList">
 <h4>DEFAULT_MAX_MOVE_PERCENT</h4>
-<pre>private static final&nbsp;float <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.MoveCostFunction.html#line.1156">DEFAULT_MAX_MOVE_PERCENT</a></pre>
+<pre>private static final&nbsp;float <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.MoveCostFunction.html#line.1158">DEFAULT_MAX_MOVE_PERCENT</a></pre>
 <dl>
 <dt><span class="seeLabel">See Also:</span></dt>
 <dd><a href="../../../../../../constant-values.html#org.apache.hadoop.hbase.master.balancer.StochasticLoadBalancer.MoveCostFunction.DEFAULT_MAX_MOVE_PERCENT">Constant Field Values</a></dd>
@@ -307,7 +307,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/Stoch
 <ul class="blockListLast">
 <li class="blockList">
 <h4>maxMovesPercent</h4>
-<pre>private final&nbsp;float <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.MoveCostFunction.html#line.1158">maxMovesPercent</a></pre>
+<pre>private final&nbsp;float <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.MoveCostFunction.html#line.1160">maxMovesPercent</a></pre>
 </li>
 </ul>
 </li>
@@ -324,7 +324,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/Stoch
 <ul class="blockListLast">
 <li class="blockList">
 <h4>MoveCostFunction</h4>
-<pre><a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.MoveCostFunction.html#line.1160">MoveCostFunction</a>(org.apache.hadoop.conf.Configuration&nbsp;conf)</pre>
+<pre><a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.MoveCostFunction.html#line.1162">MoveCostFunction</a>(org.apache.hadoop.conf.Configuration&nbsp;conf)</pre>
 </li>
 </ul>
 </li>
@@ -341,7 +341,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/Stoch
 <ul class="blockListLast">
 <li class="blockList">
 <h4>cost</h4>
-<pre>protected&nbsp;double&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.MoveCostFunction.html#line.1171">cost</a>()</pre>
+<pre>protected&nbsp;double&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.MoveCostFunction.html#line.1173">cost</a>()</pre>
 <dl>
 <dt><span class="overrideSpecifyLabel">Specified by:</span></dt>
 <dd><code><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CostFunction.html#cost--">cost</a></code>&nbsp;in class&nbsp;<code><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CostFunction.html" title="class in org.apache.hadoop.hbase.master.balancer">StochasticLoadBalancer.CostFunction</a></code></dd>
diff --git a/devapidocs/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.PrimaryRegionCountSkewCostFunction.html b/devapidocs/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.PrimaryRegionCountSkewCostFunction.html
index af7adcb..7360bb7 100644
--- a/devapidocs/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.PrimaryRegionCountSkewCostFunction.html
+++ b/devapidocs/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.PrimaryRegionCountSkewCostFunction.html
@@ -118,7 +118,7 @@ var activeTableTab = "activeTableTab";
 </dl>
 <hr>
 <br>
-<pre>static class <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.html#line.1223">StochasticLoadBalancer.PrimaryRegionCountSkewCostFunction</a>
+<pre>static class <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.html#line.1225">StochasticLoadBalancer.PrimaryRegionCountSkewCostFunction</a>
 extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CostFunction.html" title="class in org.apache.hadoop.hbase.master.balancer">StochasticLoadBalancer.CostFunction</a></pre>
 <div class="block">Compute the cost of a potential cluster state from skew in number of
  primary regions on a cluster.</div>
@@ -230,7 +230,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/Stoch
 <ul class="blockList">
 <li class="blockList">
 <h4>PRIMARY_REGION_COUNT_SKEW_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/StochasticLoadBalancer.PrimaryRegionCountSkewCostFunction.html#line.1224">PRIMARY_REGION_COUNT_SKEW_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/StochasticLoadBalancer.PrimaryRegionCountSkewCostFunction.html#line.1226">PRIMARY_REGION_COUNT_SKEW_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.StochasticLoadBalancer.PrimaryRegionCountSkewCostFunction.PRIMARY_REGION_COUNT_SKEW_COST_KEY">Constant Field Values</a></dd>
@@ -243,7 +243,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/Stoch
 <ul class="blockList">
 <li class="blockList">
 <h4>DEFAULT_PRIMARY_REGION_COUNT_SKEW_COST</h4>
-<pre>private static final&nbsp;float <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.PrimaryRegionCountSkewCostFunction.html#line.1226">DEFAULT_PRIMARY_REGION_COUNT_SKEW_COST</a></pre>
+<pre>private static final&nbsp;float <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.PrimaryRegionCountSkewCostFunction.html#line.1228">DEFAULT_PRIMARY_REGION_COUNT_SKEW_COST</a></pre>
 <dl>
 <dt><span class="seeLabel">See Also:</span></dt>
 <dd><a href="../../../../../../constant-values.html#org.apache.hadoop.hbase.master.balancer.StochasticLoadBalancer.PrimaryRegionCountSkewCostFunction.DEFAULT_PRIMARY_REGION_COUNT_SKEW_COST">Constant Field Values</a></dd>
@@ -256,7 +256,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/Stoch
 <ul class="blockListLast">
 <li class="blockList">
 <h4>stats</h4>
-<pre>private&nbsp;double[] <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.PrimaryRegionCountSkewCostFunction.html#line.1228">stats</a></pre>
+<pre>private&nbsp;double[] <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.PrimaryRegionCountSkewCostFunction.html#line.1230">stats</a></pre>
 </li>
 </ul>
 </li>
@@ -273,7 +273,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/Stoch
 <ul class="blockListLast">
 <li class="blockList">
 <h4>PrimaryRegionCountSkewCostFunction</h4>
-<pre><a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.PrimaryRegionCountSkewCostFunction.html#line.1230">PrimaryRegionCountSkewCostFunction</a>(org.apache.hadoop.conf.Configuration&nbsp;conf)</pre>
+<pre><a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.PrimaryRegionCountSkewCostFunction.html#line.1232">PrimaryRegionCountSkewCostFunction</a>(org.apache.hadoop.conf.Configuration&nbsp;conf)</pre>
 </li>
 </ul>
 </li>
@@ -290,7 +290,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/Stoch
 <ul class="blockListLast">
 <li class="blockList">
 <h4>cost</h4>
-<pre>protected&nbsp;double&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.PrimaryRegionCountSkewCostFunction.html#line.1238">cost</a>()</pre>
+<pre>protected&nbsp;double&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.PrimaryRegionCountSkewCostFunction.html#line.1240">cost</a>()</pre>
 <dl>
 <dt><span class="overrideSpecifyLabel">Specified by:</span></dt>
 <dd><code><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CostFunction.html#cost--">cost</a></code>&nbsp;in class&nbsp;<code><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CostFunction.html" title="class in org.apache.hadoop.hbase.master.balancer">StochasticLoadBalancer.CostFunction</a></code></dd>
diff --git a/devapidocs/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.RackLocalityCostFunction.html b/devapidocs/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.RackLocalityCostFunction.html
index 28f2cd0..de752bb 100644
--- a/devapidocs/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.RackLocalityCostFunction.html
+++ b/devapidocs/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.RackLocalityCostFunction.html
@@ -123,7 +123,7 @@ var activeTableTab = "activeTableTab";
 </dl>
 <hr>
 <br>
-<pre>static class <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.html#line.1393">StochasticLoadBalancer.RackLocalityCostFunction</a>
+<pre>static class <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.html#line.1395">StochasticLoadBalancer.RackLocalityCostFunction</a>
 extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.LocalityBasedCostFunction.html" title="class in org.apache.hadoop.hbase.master.balancer">StochasticLoadBalancer.LocalityBasedCostFunction</a></pre>
 </li>
 </ul>
@@ -239,7 +239,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/Stoch
 <ul class="blockList">
 <li class="blockList">
 <h4>RACK_LOCALITY_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/StochasticLoadBalancer.RackLocalityCostFunction.html#line.1395">RACK_LOCALITY_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/StochasticLoadBalancer.RackLocalityCostFunction.html#line.1397">RACK_LOCALITY_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.StochasticLoadBalancer.RackLocalityCostFunction.RACK_LOCALITY_COST_KEY">Constant Field Values</a></dd>
@@ -252,7 +252,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/Stoch
 <ul class="blockListLast">
 <li class="blockList">
 <h4>DEFAULT_RACK_LOCALITY_COST</h4>
-<pre>private static final&nbsp;float <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.RackLocalityCostFunction.html#line.1396">DEFAULT_RACK_LOCALITY_COST</a></pre>
+<pre>private static final&nbsp;float <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.RackLocalityCostFunction.html#line.1398">DEFAULT_RACK_LOCALITY_COST</a></pre>
 <dl>
 <dt><span class="seeLabel">See Also:</span></dt>
 <dd><a href="../../../../../../constant-values.html#org.apache.hadoop.hbase.master.balancer.StochasticLoadBalancer.RackLocalityCostFunction.DEFAULT_RACK_LOCALITY_COST">Constant Field Values</a></dd>
@@ -273,7 +273,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/Stoch
 <ul class="blockListLast">
 <li class="blockList">
 <h4>RackLocalityCostFunction</h4>
-<pre>public&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.RackLocalityCostFunction.html#line.1398">RackLocalityCostFunction</a>(org.apache.hadoop.conf.Configuration&nbsp;conf,
+<pre>public&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.RackLocalityCostFunction.html#line.1400">RackLocalityCostFunction</a>(org.apache.hadoop.conf.Configuration&nbsp;conf,
                                 <a href="../../../../../../org/apache/hadoop/hbase/master/MasterServices.html" title="interface in org.apache.hadoop.hbase.master">MasterServices</a>&nbsp;services)</pre>
 </li>
 </ul>
@@ -291,7 +291,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/Stoch
 <ul class="blockListLast">
 <li class="blockList">
 <h4>regionIndexToEntityIndex</h4>
-<pre>int&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.RackLocalityCostFunction.html#line.1409">regionIndexToEntityIndex</a>(int&nbsp;region)</pre>
+<pre>int&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.RackLocalityCostFunction.html#line.1411">regionIndexToEntityIndex</a>(int&nbsp;region)</pre>
 <div class="block"><span class="descfrmTypeLabel">Description copied from class:&nbsp;<code><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.LocalityBasedCostFunction.html#regionIndexToEntityIndex-int-">StochasticLoadBalancer.LocalityBasedCostFunction</a></code></span></div>
 <div class="block">Maps region to the current entity (server or rack) on which it is stored</div>
 <dl>
diff --git a/devapidocs/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.RandomCandidateGenerator.html b/devapidocs/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.RandomCandidateGenerator.html
index b3292d0..6977996 100644
--- a/devapidocs/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.RandomCandidateGenerator.html
+++ b/devapidocs/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.RandomCandidateGenerator.html
@@ -118,7 +118,7 @@ var activeTableTab = "activeTableTab";
 </dl>
 <hr>
 <br>
-<pre>static class <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.html#line.774">StochasticLoadBalancer.RandomCandidateGenerator</a>
+<pre>static class <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.html#line.776">StochasticLoadBalancer.RandomCandidateGenerator</a>
 extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CandidateGenerator.html" title="class in org.apache.hadoop.hbase.master.balancer">StochasticLoadBalancer.CandidateGenerator</a></pre>
 </li>
 </ul>
@@ -194,7 +194,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/Stoch
 <ul class="blockListLast">
 <li class="blockList">
 <h4>RandomCandidateGenerator</h4>
-<pre><a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.RandomCandidateGenerator.html#line.774">RandomCandidateGenerator</a>()</pre>
+<pre><a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.RandomCandidateGenerator.html#line.776">RandomCandidateGenerator</a>()</pre>
 </li>
 </ul>
 </li>
@@ -211,7 +211,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/Stoch
 <ul class="blockListLast">
 <li class="blockList">
 <h4>generate</h4>
-<pre><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BaseLoadBalancer.Cluster.Action.html" title="class in org.apache.hadoop.hbase.master.balancer">BaseLoadBalancer.Cluster.Action</a>&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.RandomCandidateGenerator.html#line.777">generate</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BaseLoadBalancer.Cluster.html" title="class in org.apache.hadoop. [...]
+<pre><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BaseLoadBalancer.Cluster.Action.html" title="class in org.apache.hadoop.hbase.master.balancer">BaseLoadBalancer.Cluster.Action</a>&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.RandomCandidateGenerator.html#line.779">generate</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BaseLoadBalancer.Cluster.html" title="class in org.apache.hadoop. [...]
 <dl>
 <dt><span class="overrideSpecifyLabel">Specified by:</span></dt>
 <dd><code><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CandidateGenerator.html#generate-org.apache.hadoop.hbase.master.balancer.BaseLoadBalancer.Cluster-">generate</a></code>&nbsp;in class&nbsp;<code><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CandidateGenerator.html" title="class in org.apache.hadoop.hbase.master.balancer">StochasticLoadBalancer.CandidateGenerator</a></code></dd>
diff --git a/devapidocs/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.ReadRequestCostFunction.html b/devapidocs/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.ReadRequestCostFunction.html
index a0388a7..6eb47cd 100644
--- a/devapidocs/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.ReadRequestCostFunction.html
+++ b/devapidocs/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.ReadRequestCostFunction.html
@@ -128,7 +128,7 @@ var activeTableTab = "activeTableTab";
 </dl>
 <hr>
 <br>
-<pre>static class <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.html#line.1512">StochasticLoadBalancer.ReadRequestCostFunction</a>
+<pre>static class <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.html#line.1514">StochasticLoadBalancer.ReadRequestCostFunction</a>
 extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CostFromRegionLoadAsRateFunction.html" title="class in org.apache.hadoop.hbase.master.balancer">StochasticLoadBalancer.CostFromRegionLoadAsRateFunction</a></pre>
 <div class="block">Compute the cost of total number of read requests  The more unbalanced the higher the
  computed cost will be.  This uses a rolling average of regionload.</div>
@@ -250,7 +250,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/Stoch
 <ul class="blockList">
 <li class="blockList">
 <h4>READ_REQUEST_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/StochasticLoadBalancer.ReadRequestCostFunction.html#line.1514">READ_REQUEST_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/StochasticLoadBalancer.ReadRequestCostFunction.html#line.1516">READ_REQUEST_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.StochasticLoadBalancer.ReadRequestCostFunction.READ_REQUEST_COST_KEY">Constant Field Values</a></dd>
@@ -263,7 +263,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/Stoch
 <ul class="blockListLast">
 <li class="blockList">
 <h4>DEFAULT_READ_REQUEST_COST</h4>
-<pre>private static final&nbsp;float <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.ReadRequestCostFunction.html#line.1516">DEFAULT_READ_REQUEST_COST</a></pre>
+<pre>private static final&nbsp;float <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.ReadRequestCostFunction.html#line.1518">DEFAULT_READ_REQUEST_COST</a></pre>
 <dl>
 <dt><span class="seeLabel">See Also:</span></dt>
 <dd><a href="../../../../../../constant-values.html#org.apache.hadoop.hbase.master.balancer.StochasticLoadBalancer.ReadRequestCostFunction.DEFAULT_READ_REQUEST_COST">Constant Field Values</a></dd>
@@ -284,7 +284,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/Stoch
 <ul class="blockListLast">
 <li class="blockList">
 <h4>ReadRequestCostFunction</h4>
-<pre><a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.ReadRequestCostFunction.html#line.1518">ReadRequestCostFunction</a>(org.apache.hadoop.conf.Configuration&nbsp;conf)</pre>
+<pre><a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.ReadRequestCostFunction.html#line.1520">ReadRequestCostFunction</a>(org.apache.hadoop.conf.Configuration&nbsp;conf)</pre>
 </li>
 </ul>
 </li>
@@ -301,7 +301,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/Stoch
 <ul class="blockListLast">
 <li class="blockList">
 <h4>getCostFromRl</h4>
-<pre>protected&nbsp;double&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.ReadRequestCostFunction.html#line.1524">getCostFromRl</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BalancerRegionLoad.html" title="class in org.apache.hadoop.hbase.master.balancer">BalancerRegionLoad</a>&nbsp;rl)</pre>
+<pre>protected&nbsp;double&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.ReadRequestCostFunction.html#line.1526">getCostFromRl</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BalancerRegionLoad.html" title="class in org.apache.hadoop.hbase.master.balancer">BalancerRegionLoad</a>&nbsp;rl)</pre>
 <dl>
 <dt><span class="overrideSpecifyLabel">Specified by:</span></dt>
 <dd><code><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CostFromRegionLoadFunction.html#getCostFromRl-org.apache.hadoop.hbase.master.balancer.BalancerRegionLoad-">getCostFromRl</a></code>&nbsp;in class&nbsp;<code><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CostFromRegionLoadFunction.html" title="class in org.apache.hadoop.hbase.master.balancer">StochasticLoadBalancer.CostFromRegionLoadFunction</a></ [...]
diff --git a/devapidocs/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.RegionCountSkewCostFunction.html b/devapidocs/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.RegionCountSkewCostFunction.html
index f94d54c..3100aad 100644
--- a/devapidocs/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.RegionCountSkewCostFunction.html
+++ b/devapidocs/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.RegionCountSkewCostFunction.html
@@ -118,7 +118,7 @@ var activeTableTab = "activeTableTab";
 </dl>
 <hr>
 <br>
-<pre>static class <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.html#line.1192">StochasticLoadBalancer.RegionCountSkewCostFunction</a>
+<pre>static class <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.html#line.1194">StochasticLoadBalancer.RegionCountSkewCostFunction</a>
 extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CostFunction.html" title="class in org.apache.hadoop.hbase.master.balancer">StochasticLoadBalancer.CostFunction</a></pre>
 <div class="block">Compute the cost of a potential cluster state from skew in number of
  regions on a cluster.</div>
@@ -230,7 +230,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/Stoch
 <ul class="blockList">
 <li class="blockList">
 <h4>REGION_COUNT_SKEW_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/StochasticLoadBalancer.RegionCountSkewCostFunction.html#line.1193">REGION_COUNT_SKEW_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/StochasticLoadBalancer.RegionCountSkewCostFunction.html#line.1195">REGION_COUNT_SKEW_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.StochasticLoadBalancer.RegionCountSkewCostFunction.REGION_COUNT_SKEW_COST_KEY">Constant Field Values</a></dd>
@@ -243,7 +243,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/Stoch
 <ul class="blockList">
 <li class="blockList">
 <h4>DEFAULT_REGION_COUNT_SKEW_COST</h4>
-<pre>private static final&nbsp;float <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.RegionCountSkewCostFunction.html#line.1195">DEFAULT_REGION_COUNT_SKEW_COST</a></pre>
+<pre>private static final&nbsp;float <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.RegionCountSkewCostFunction.html#line.1197">DEFAULT_REGION_COUNT_SKEW_COST</a></pre>
 <dl>
 <dt><span class="seeLabel">See Also:</span></dt>
 <dd><a href="../../../../../../constant-values.html#org.apache.hadoop.hbase.master.balancer.StochasticLoadBalancer.RegionCountSkewCostFunction.DEFAULT_REGION_COUNT_SKEW_COST">Constant Field Values</a></dd>
@@ -256,7 +256,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/Stoch
 <ul class="blockListLast">
 <li class="blockList">
 <h4>stats</h4>
-<pre>private&nbsp;double[] <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.RegionCountSkewCostFunction.html#line.1197">stats</a></pre>
+<pre>private&nbsp;double[] <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.RegionCountSkewCostFunction.html#line.1199">stats</a></pre>
 </li>
 </ul>
 </li>
@@ -273,7 +273,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/Stoch
 <ul class="blockListLast">
 <li class="blockList">
 <h4>RegionCountSkewCostFunction</h4>
-<pre><a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.RegionCountSkewCostFunction.html#line.1199">RegionCountSkewCostFunction</a>(org.apache.hadoop.conf.Configuration&nbsp;conf)</pre>
+<pre><a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.RegionCountSkewCostFunction.html#line.1201">RegionCountSkewCostFunction</a>(org.apache.hadoop.conf.Configuration&nbsp;conf)</pre>
 </li>
 </ul>
 </li>
@@ -290,7 +290,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/Stoch
 <ul class="blockListLast">
 <li class="blockList">
 <h4>cost</h4>
-<pre>protected&nbsp;double&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.RegionCountSkewCostFunction.html#line.1206">cost</a>()</pre>
+<pre>protected&nbsp;double&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.RegionCountSkewCostFunction.html#line.1208">cost</a>()</pre>
 <dl>
 <dt><span class="overrideSpecifyLabel">Specified by:</span></dt>
 <dd><code><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CostFunction.html#cost--">cost</a></code>&nbsp;in class&nbsp;<code><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CostFunction.html" title="class in org.apache.hadoop.hbase.master.balancer">StochasticLoadBalancer.CostFunction</a></code></dd>
diff --git a/devapidocs/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.RegionReplicaCandidateGenerator.html b/devapidocs/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.RegionReplicaCandidateGenerator.html
index 4d4d6c8..88a803a 100644
--- a/devapidocs/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.RegionReplicaCandidateGenerator.html
+++ b/devapidocs/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.RegionReplicaCandidateGenerator.html
@@ -122,7 +122,7 @@ var activeTableTab = "activeTableTab";
 </dl>
 <hr>
 <br>
-<pre>static class <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.html#line.903">StochasticLoadBalancer.RegionReplicaCandidateGenerator</a>
+<pre>static class <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.html#line.905">StochasticLoadBalancer.RegionReplicaCandidateGenerator</a>
 extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CandidateGenerator.html" title="class in org.apache.hadoop.hbase.master.balancer">StochasticLoadBalancer.CandidateGenerator</a></pre>
 <div class="block">Generates candidates which moves the replicas out of the region server for
  co-hosted region replicas</div>
@@ -228,7 +228,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/Stoch
 <ul class="blockListLast">
 <li class="blockList">
 <h4>randomGenerator</h4>
-<pre><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.RandomCandidateGenerator.html" title="class in org.apache.hadoop.hbase.master.balancer">StochasticLoadBalancer.RandomCandidateGenerator</a> <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.RegionReplicaCandidateGenerator.html#line.905">randomGenerator</a></pre>
+<pre><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.RandomCandidateGenerator.html" title="class in org.apache.hadoop.hbase.master.balancer">StochasticLoadBalancer.RandomCandidateGenerator</a> <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.RegionReplicaCandidateGenerator.html#line.907">randomGenerator</a></pre>
 </li>
 </ul>
 </li>
@@ -245,7 +245,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/Stoch
 <ul class="blockListLast">
 <li class="blockList">
 <h4>RegionReplicaCandidateGenerator</h4>
-<pre><a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.RegionReplicaCandidateGenerator.html#line.903">RegionReplicaCandidateGenerator</a>()</pre>
+<pre><a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.RegionReplicaCandidateGenerator.html#line.905">RegionReplicaCandidateGenerator</a>()</pre>
 </li>
 </ul>
 </li>
@@ -262,7 +262,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/Stoch
 <ul class="blockList">
 <li class="blockList">
 <h4>selectCoHostedRegionPerGroup</h4>
-<pre>int&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.RegionReplicaCandidateGenerator.html#line.916">selectCoHostedRegionPerGroup</a>(int[]&nbsp;primariesOfRegionsPerGroup,
+<pre>int&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.RegionReplicaCandidateGenerator.html#line.918">selectCoHostedRegionPerGroup</a>(int[]&nbsp;primariesOfRegionsPerGroup,
                                  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
@@ -284,7 +284,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/Stoch
 <ul class="blockListLast">
 <li class="blockList">
 <h4>generate</h4>
-<pre><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BaseLoadBalancer.Cluster.Action.html" title="class in org.apache.hadoop.hbase.master.balancer">BaseLoadBalancer.Cluster.Action</a>&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.RegionReplicaCandidateGenerator.html#line.960">generate</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BaseLoadBalancer.Cluster.html" title="class in org.apache. [...]
+<pre><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BaseLoadBalancer.Cluster.Action.html" title="class in org.apache.hadoop.hbase.master.balancer">BaseLoadBalancer.Cluster.Action</a>&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.RegionReplicaCandidateGenerator.html#line.962">generate</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BaseLoadBalancer.Cluster.html" title="class in org.apache. [...]
 <dl>
 <dt><span class="overrideSpecifyLabel">Specified by:</span></dt>
 <dd><code><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CandidateGenerator.html#generate-org.apache.hadoop.hbase.master.balancer.BaseLoadBalancer.Cluster-">generate</a></code>&nbsp;in class&nbsp;<code><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CandidateGenerator.html" title="class in org.apache.hadoop.hbase.master.balancer">StochasticLoadBalancer.CandidateGenerator</a></code></dd>
diff --git a/devapidocs/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.RegionReplicaHostCostFunction.html b/devapidocs/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.RegionReplicaHostCostFunction.html
index ba20e38..306f86c 100644
--- a/devapidocs/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.RegionReplicaHostCostFunction.html
+++ b/devapidocs/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.RegionReplicaHostCostFunction.html
@@ -122,7 +122,7 @@ var activeTableTab = "activeTableTab";
 </dl>
 <hr>
 <br>
-<pre>static class <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.html#line.1578">StochasticLoadBalancer.RegionReplicaHostCostFunction</a>
+<pre>static class <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.html#line.1580">StochasticLoadBalancer.RegionReplicaHostCostFunction</a>
 extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CostFunction.html" title="class in org.apache.hadoop.hbase.master.balancer">StochasticLoadBalancer.CostFunction</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
@@ -272,7 +272,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/Stoch
 <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/StochasticLoadBalancer.RegionReplicaHostCostFunction.html#line.1579">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/StochasticLoadBalancer.RegionReplicaHostCostFunction.html#line.1581">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.StochasticLoadBalancer.RegionReplicaHostCostFunction.REGION_REPLICA_HOST_COST_KEY">Constant Field Values</a></dd>
@@ -285,7 +285,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/Stoch
 <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/StochasticLoadBalancer.RegionReplicaHostCostFunction.html#line.1581">DEFAULT_REGION_REPLICA_HOST_COST_KEY</a></pre>
+<pre>private static final&nbsp;float <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.RegionReplicaHostCostFunction.html#line.1583">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.StochasticLoadBalancer.RegionReplicaHostCostFunction.DEFAULT_REGION_REPLICA_HOST_COST_KEY">Constant Field Values</a></dd>
@@ -298,7 +298,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/Stoch
 <ul class="blockList">
 <li class="blockList">
 <h4>maxCost</h4>
-<pre>long <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.RegionReplicaHostCostFunction.html#line.1583">maxCost</a></pre>
+<pre>long <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.RegionReplicaHostCostFunction.html#line.1585">maxCost</a></pre>
 </li>
 </ul>
 <a name="costsPerGroup">
@@ -307,7 +307,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/Stoch
 <ul class="blockList">
 <li class="blockList">
 <h4>costsPerGroup</h4>
-<pre>long[] <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.RegionReplicaHostCostFunction.html#line.1584">costsPerGroup</a></pre>
+<pre>long[] <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.RegionReplicaHostCostFunction.html#line.1586">costsPerGroup</a></pre>
 </li>
 </ul>
 <a name="primariesOfRegionsPerGroup">
@@ -316,7 +316,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/Stoch
 <ul class="blockListLast">
 <li class="blockList">
 <h4>primariesOfRegionsPerGroup</h4>
-<pre>int[][] <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.RegionReplicaHostCostFunction.html#line.1585">primariesOfRegionsPerGroup</a></pre>
+<pre>int[][] <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.RegionReplicaHostCostFunction.html#line.1587">primariesOfRegionsPerGroup</a></pre>
 </li>
 </ul>
 </li>
@@ -333,7 +333,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/Stoch
 <ul class="blockListLast">
 <li class="blockList">
 <h4>RegionReplicaHostCostFunction</h4>
-<pre>public&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.RegionReplicaHostCostFunction.html#line.1587">RegionReplicaHostCostFunction</a>(org.apache.hadoop.conf.Configuration&nbsp;conf)</pre>
+<pre>public&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.RegionReplicaHostCostFunction.html#line.1589">RegionReplicaHostCostFunction</a>(org.apache.hadoop.conf.Configuration&nbsp;conf)</pre>
 </li>
 </ul>
 </li>
@@ -350,7 +350,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/Stoch
 <ul class="blockList">
 <li class="blockList">
 <h4>init</h4>
-<pre>void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.RegionReplicaHostCostFunction.html#line.1594">init</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BaseLoadBalancer.Cluster.html" title="class in org.apache.hadoop.hbase.master.balancer">BaseLoadBalancer.Cluster</a>&nbsp;cluster)</pre>
+<pre>void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.RegionReplicaHostCostFunction.html#line.1596">init</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BaseLoadBalancer.Cluster.html" title="class in org.apache.hadoop.hbase.master.balancer">BaseLoadBalancer.Cluster</a>&nbsp;cluster)</pre>
 <div class="block"><span class="descfrmTypeLabel">Description copied from class:&nbsp;<code><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CostFunction.html#init-org.apache.hadoop.hbase.master.balancer.BaseLoadBalancer.Cluster-">StochasticLoadBalancer.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>
@@ -366,7 +366,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/Stoch
 <ul class="blockList">
 <li class="blockList">
 <h4>getMaxCost</h4>
-<pre>long&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.RegionReplicaHostCostFunction.html#line.1607">getMaxCost</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BaseLoadBalancer.Cluster.html" title="class in org.apache.hadoop.hbase.master.balancer">BaseLoadBalancer.Cluster</a>&nbsp;cluster)</pre>
+<pre>long&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.RegionReplicaHostCostFunction.html#line.1609">getMaxCost</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BaseLoadBalancer.Cluster.html" title="class in org.apache.hadoop.hbase.master.balancer">BaseLoadBalancer.Cluster</a>&nbsp;cluster)</pre>
 </li>
 </ul>
 <a name="isNeeded--">
@@ -375,7 +375,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/Stoch
 <ul class="blockList">
 <li class="blockList">
 <h4>isNeeded</h4>
-<pre>boolean&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.RegionReplicaHostCostFunction.html#line.1623">isNeeded</a>()</pre>
+<pre>boolean&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.RegionReplicaHostCostFunction.html#line.1625">isNeeded</a>()</pre>
 <dl>
 <dt><span class="overrideSpecifyLabel">Overrides:</span></dt>
 <dd><code><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CostFunction.html#isNeeded--">isNeeded</a></code>&nbsp;in class&nbsp;<code><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CostFunction.html" title="class in org.apache.hadoop.hbase.master.balancer">StochasticLoadBalancer.CostFunction</a></code></dd>
@@ -388,7 +388,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/Stoch
 <ul class="blockList">
 <li class="blockList">
 <h4>cost</h4>
-<pre>protected&nbsp;double&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.RegionReplicaHostCostFunction.html#line.1628">cost</a>()</pre>
+<pre>protected&nbsp;double&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.RegionReplicaHostCostFunction.html#line.1630">cost</a>()</pre>
 <dl>
 <dt><span class="overrideSpecifyLabel">Specified by:</span></dt>
 <dd><code><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CostFunction.html#cost--">cost</a></code>&nbsp;in class&nbsp;<code><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CostFunction.html" title="class in org.apache.hadoop.hbase.master.balancer">StochasticLoadBalancer.CostFunction</a></code></dd>
@@ -401,7 +401,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/Stoch
 <ul class="blockList">
 <li class="blockList">
 <h4>costPerGroup</h4>
-<pre>protected&nbsp;long&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.RegionReplicaHostCostFunction.html#line.1648">costPerGroup</a>(int[]&nbsp;primariesOfRegions)</pre>
+<pre>protected&nbsp;long&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.RegionReplicaHostCostFunction.html#line.1650">costPerGroup</a>(int[]&nbsp;primariesOfRegions)</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
@@ -420,7 +420,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/Stoch
 <ul class="blockListLast">
 <li class="blockList">
 <h4>regionMoved</h4>
-<pre>protected&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.RegionReplicaHostCostFunction.html#line.1671">regionMoved</a>(int&nbsp;region,
+<pre>protected&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.RegionReplicaHostCostFunction.html#line.1673">regionMoved</a>(int&nbsp;region,
                            int&nbsp;oldServer,
                            int&nbsp;newServer)</pre>
 <dl>
diff --git a/devapidocs/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.RegionReplicaRackCandidateGenerator.html b/devapidocs/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.RegionReplicaRackCandidateGenerator.html
index 6826db1..5861af9 100644
--- a/devapidocs/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.RegionReplicaRackCandidateGenerator.html
+++ b/devapidocs/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.RegionReplicaRackCandidateGenerator.html
@@ -123,7 +123,7 @@ var activeTableTab = "activeTableTab";
 </dl>
 <hr>
 <br>
-<pre>static class <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.html#line.987">StochasticLoadBalancer.RegionReplicaRackCandidateGenerator</a>
+<pre>static class <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.html#line.989">StochasticLoadBalancer.RegionReplicaRackCandidateGenerator</a>
 extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.RegionReplicaCandidateGenerator.html" title="class in org.apache.hadoop.hbase.master.balancer">StochasticLoadBalancer.RegionReplicaCandidateGenerator</a></pre>
 <div class="block">Generates candidates which moves the replicas out of the rack for
  co-hosted region replicas in the same rack</div>
@@ -223,7 +223,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/Stoch
 <ul class="blockListLast">
 <li class="blockList">
 <h4>RegionReplicaRackCandidateGenerator</h4>
-<pre><a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.RegionReplicaRackCandidateGenerator.html#line.987">RegionReplicaRackCandidateGenerator</a>()</pre>
+<pre><a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.RegionReplicaRackCandidateGenerator.html#line.989">RegionReplicaRackCandidateGenerator</a>()</pre>
 </li>
 </ul>
 </li>
@@ -240,7 +240,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/Stoch
 <ul class="blockListLast">
 <li class="blockList">
 <h4>generate</h4>
-<pre><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BaseLoadBalancer.Cluster.Action.html" title="class in org.apache.hadoop.hbase.master.balancer">BaseLoadBalancer.Cluster.Action</a>&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.RegionReplicaRackCandidateGenerator.html#line.989">generate</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BaseLoadBalancer.Cluster.html" title="class in org.apa [...]
+<pre><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BaseLoadBalancer.Cluster.Action.html" title="class in org.apache.hadoop.hbase.master.balancer">BaseLoadBalancer.Cluster.Action</a>&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.RegionReplicaRackCandidateGenerator.html#line.991">generate</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BaseLoadBalancer.Cluster.html" title="class in org.apa [...]
 <dl>
 <dt><span class="overrideSpecifyLabel">Overrides:</span></dt>
 <dd><code><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.RegionReplicaCandidateGenerator.html#generate-org.apache.hadoop.hbase.master.balancer.BaseLoadBalancer.Cluster-">generate</a></code>&nbsp;in class&nbsp;<code><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.RegionReplicaCandidateGenerator.html" title="class in org.apache.hadoop.hbase.master.balancer">StochasticLoadBalancer.RegionReplicaCandidateGene [...]
diff --git a/devapidocs/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.RegionReplicaRackCostFunction.html b/devapidocs/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.RegionReplicaRackCostFunction.html
index 062ff7c..63fb292 100644
--- a/devapidocs/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.RegionReplicaRackCostFunction.html
+++ b/devapidocs/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.RegionReplicaRackCostFunction.html
@@ -123,7 +123,7 @@ var activeTableTab = "activeTableTab";
 </dl>
 <hr>
 <br>
-<pre>static class <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.html#line.1694">StochasticLoadBalancer.RegionReplicaRackCostFunction</a>
+<pre>static class <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.html#line.1696">StochasticLoadBalancer.RegionReplicaRackCostFunction</a>
 extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.RegionReplicaHostCostFunction.html" title="class in org.apache.hadoop.hbase.master.balancer">StochasticLoadBalancer.RegionReplicaHostCostFunction</a></pre>
 <div class="block">A cost function for region replicas for the rack distribution. We give a relatively high
  cost to hosting replicas of the same region in the same rack. We do not prevent the case
@@ -255,7 +255,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/Stoch
 <ul class="blockList">
 <li class="blockList">
 <h4>REGION_REPLICA_RACK_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/StochasticLoadBalancer.RegionReplicaRackCostFunction.html#line.1695">REGION_REPLICA_RACK_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/StochasticLoadBalancer.RegionReplicaRackCostFunction.html#line.1697">REGION_REPLICA_RACK_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.StochasticLoadBalancer.RegionReplicaRackCostFunction.REGION_REPLICA_RACK_COST_KEY">Constant Field Values</a></dd>
@@ -268,7 +268,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/Stoch
 <ul class="blockListLast">
 <li class="blockList">
 <h4>DEFAULT_REGION_REPLICA_RACK_COST_KEY</h4>
-<pre>private static final&nbsp;float <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.RegionReplicaRackCostFunction.html#line.1697">DEFAULT_REGION_REPLICA_RACK_COST_KEY</a></pre>
+<pre>private static final&nbsp;float <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.RegionReplicaRackCostFunction.html#line.1699">DEFAULT_REGION_REPLICA_RACK_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.StochasticLoadBalancer.RegionReplicaRackCostFunction.DEFAULT_REGION_REPLICA_RACK_COST_KEY">Constant Field Values</a></dd>
@@ -289,7 +289,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/Stoch
 <ul class="blockListLast">
 <li class="blockList">
 <h4>RegionReplicaRackCostFunction</h4>
-<pre>public&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.RegionReplicaRackCostFunction.html#line.1699">RegionReplicaRackCostFunction</a>(org.apache.hadoop.conf.Configuration&nbsp;conf)</pre>
+<pre>public&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.RegionReplicaRackCostFunction.html#line.1701">RegionReplicaRackCostFunction</a>(org.apache.hadoop.conf.Configuration&nbsp;conf)</pre>
 </li>
 </ul>
 </li>
@@ -306,7 +306,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/Stoch
 <ul class="blockList">
 <li class="blockList">
 <h4>init</h4>
-<pre>void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.RegionReplicaRackCostFunction.html#line.1706">init</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BaseLoadBalancer.Cluster.html" title="class in org.apache.hadoop.hbase.master.balancer">BaseLoadBalancer.Cluster</a>&nbsp;cluster)</pre>
+<pre>void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.RegionReplicaRackCostFunction.html#line.1708">init</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BaseLoadBalancer.Cluster.html" title="class in org.apache.hadoop.hbase.master.balancer">BaseLoadBalancer.Cluster</a>&nbsp;cluster)</pre>
 <div class="block"><span class="descfrmTypeLabel">Description copied from class:&nbsp;<code><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CostFunction.html#init-org.apache.hadoop.hbase.master.balancer.BaseLoadBalancer.Cluster-">StochasticLoadBalancer.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>
@@ -322,7 +322,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/Stoch
 <ul class="blockListLast">
 <li class="blockList">
 <h4>regionMoved</h4>
-<pre>protected&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.RegionReplicaRackCostFunction.html#line.1721">regionMoved</a>(int&nbsp;region,
+<pre>protected&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.RegionReplicaRackCostFunction.html#line.1723">regionMoved</a>(int&nbsp;region,
                            int&nbsp;oldServer,
                            int&nbsp;newServer)</pre>
 <dl>
diff --git a/devapidocs/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.ServerLocalityCostFunction.html b/devapidocs/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.ServerLocalityCostFunction.html
index 6f02980..fe729fa 100644
--- a/devapidocs/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.ServerLocalityCostFunction.html
+++ b/devapidocs/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.ServerLocalityCostFunction.html
@@ -123,7 +123,7 @@ var activeTableTab = "activeTableTab";
 </dl>
 <hr>
 <br>
-<pre>static class <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.html#line.1372">StochasticLoadBalancer.ServerLocalityCostFunction</a>
+<pre>static class <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.html#line.1374">StochasticLoadBalancer.ServerLocalityCostFunction</a>
 extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.LocalityBasedCostFunction.html" title="class in org.apache.hadoop.hbase.master.balancer">StochasticLoadBalancer.LocalityBasedCostFunction</a></pre>
 </li>
 </ul>
@@ -239,7 +239,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/Stoch
 <ul class="blockList">
 <li class="blockList">
 <h4>LOCALITY_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/StochasticLoadBalancer.ServerLocalityCostFunction.html#line.1374">LOCALITY_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/StochasticLoadBalancer.ServerLocalityCostFunction.html#line.1376">LOCALITY_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.StochasticLoadBalancer.ServerLocalityCostFunction.LOCALITY_COST_KEY">Constant Field Values</a></dd>
@@ -252,7 +252,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/Stoch
 <ul class="blockListLast">
 <li class="blockList">
 <h4>DEFAULT_LOCALITY_COST</h4>
-<pre>private static final&nbsp;float <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.ServerLocalityCostFunction.html#line.1375">DEFAULT_LOCALITY_COST</a></pre>
+<pre>private static final&nbsp;float <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.ServerLocalityCostFunction.html#line.1377">DEFAULT_LOCALITY_COST</a></pre>
 <dl>
 <dt><span class="seeLabel">See Also:</span></dt>
 <dd><a href="../../../../../../constant-values.html#org.apache.hadoop.hbase.master.balancer.StochasticLoadBalancer.ServerLocalityCostFunction.DEFAULT_LOCALITY_COST">Constant Field Values</a></dd>
@@ -273,7 +273,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/Stoch
 <ul class="blockListLast">
 <li class="blockList">
 <h4>ServerLocalityCostFunction</h4>
-<pre><a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.ServerLocalityCostFunction.html#line.1377">ServerLocalityCostFunction</a>(org.apache.hadoop.conf.Configuration&nbsp;conf,
+<pre><a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.ServerLocalityCostFunction.html#line.1379">ServerLocalityCostFunction</a>(org.apache.hadoop.conf.Configuration&nbsp;conf,
                            <a href="../../../../../../org/apache/hadoop/hbase/master/MasterServices.html" title="interface in org.apache.hadoop.hbase.master">MasterServices</a>&nbsp;srv)</pre>
 </li>
 </ul>
@@ -291,7 +291,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/Stoch
 <ul class="blockListLast">
 <li class="blockList">
 <h4>regionIndexToEntityIndex</h4>
-<pre>int&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.ServerLocalityCostFunction.html#line.1388">regionIndexToEntityIndex</a>(int&nbsp;region)</pre>
+<pre>int&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.ServerLocalityCostFunction.html#line.1390">regionIndexToEntityIndex</a>(int&nbsp;region)</pre>
 <div class="block"><span class="descfrmTypeLabel">Description copied from class:&nbsp;<code><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.LocalityBasedCostFunction.html#regionIndexToEntityIndex-int-">StochasticLoadBalancer.LocalityBasedCostFunction</a></code></span></div>
 <div class="block">Maps region to the current entity (server or rack) on which it is stored</div>
 <dl>
diff --git a/devapidocs/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.StoreFileCostFunction.html b/devapidocs/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.StoreFileCostFunction.html
index adf5566..9ae60ee 100644
--- a/devapidocs/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.StoreFileCostFunction.html
+++ b/devapidocs/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.StoreFileCostFunction.html
@@ -123,7 +123,7 @@ var activeTableTab = "activeTableTab";
 </dl>
 <hr>
 <br>
-<pre>static class <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.html#line.1759">StochasticLoadBalancer.StoreFileCostFunction</a>
+<pre>static class <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.html#line.1761">StochasticLoadBalancer.StoreFileCostFunction</a>
 extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CostFromRegionLoadFunction.html" title="class in org.apache.hadoop.hbase.master.balancer">StochasticLoadBalancer.CostFromRegionLoadFunction</a></pre>
 <div class="block">Compute the cost of total open storefiles size.  The more unbalanced the higher the
  computed cost will be.  This uses a rolling average of regionload.</div>
@@ -238,7 +238,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/Stoch
 <ul class="blockList">
 <li class="blockList">
 <h4>STOREFILE_SIZE_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/StochasticLoadBalancer.StoreFileCostFunction.html#line.1761">STOREFILE_SIZE_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/StochasticLoadBalancer.StoreFileCostFunction.html#line.1763">STOREFILE_SIZE_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.StochasticLoadBalancer.StoreFileCostFunction.STOREFILE_SIZE_COST_KEY">Constant Field Values</a></dd>
@@ -251,7 +251,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/Stoch
 <ul class="blockListLast">
 <li class="blockList">
 <h4>DEFAULT_STOREFILE_SIZE_COST</h4>
-<pre>private static final&nbsp;float <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.StoreFileCostFunction.html#line.1763">DEFAULT_STOREFILE_SIZE_COST</a></pre>
+<pre>private static final&nbsp;float <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.StoreFileCostFunction.html#line.1765">DEFAULT_STOREFILE_SIZE_COST</a></pre>
 <dl>
 <dt><span class="seeLabel">See Also:</span></dt>
 <dd><a href="../../../../../../constant-values.html#org.apache.hadoop.hbase.master.balancer.StochasticLoadBalancer.StoreFileCostFunction.DEFAULT_STOREFILE_SIZE_COST">Constant Field Values</a></dd>
@@ -272,7 +272,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/Stoch
 <ul class="blockListLast">
 <li class="blockList">
 <h4>StoreFileCostFunction</h4>
-<pre><a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.StoreFileCostFunction.html#line.1765">StoreFileCostFunction</a>(org.apache.hadoop.conf.Configuration&nbsp;conf)</pre>
+<pre><a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.StoreFileCostFunction.html#line.1767">StoreFileCostFunction</a>(org.apache.hadoop.conf.Configuration&nbsp;conf)</pre>
 </li>
 </ul>
 </li>
@@ -289,7 +289,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/Stoch
 <ul class="blockListLast">
 <li class="blockList">
 <h4>getCostFromRl</h4>
-<pre>protected&nbsp;double&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.StoreFileCostFunction.html#line.1771">getCostFromRl</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BalancerRegionLoad.html" title="class in org.apache.hadoop.hbase.master.balancer">BalancerRegionLoad</a>&nbsp;rl)</pre>
+<pre>protected&nbsp;double&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.StoreFileCostFunction.html#line.1773">getCostFromRl</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BalancerRegionLoad.html" title="class in org.apache.hadoop.hbase.master.balancer">BalancerRegionLoad</a>&nbsp;rl)</pre>
 <dl>
 <dt><span class="overrideSpecifyLabel">Specified by:</span></dt>
 <dd><code><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CostFromRegionLoadFunction.html#getCostFromRl-org.apache.hadoop.hbase.master.balancer.BalancerRegionLoad-">getCostFromRl</a></code>&nbsp;in class&nbsp;<code><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CostFromRegionLoadFunction.html" title="class in org.apache.hadoop.hbase.master.balancer">StochasticLoadBalancer.CostFromRegionLoadFunction</a></ [...]
diff --git a/devapidocs/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.TableSkewCostFunction.html b/devapidocs/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.TableSkewCostFunction.html
index 0641bdc..e9839c7 100644
--- a/devapidocs/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.TableSkewCostFunction.html
+++ b/devapidocs/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.TableSkewCostFunction.html
@@ -118,7 +118,7 @@ var activeTableTab = "activeTableTab";
 </dl>
 <hr>
 <br>
-<pre>static class <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.html#line.1263">StochasticLoadBalancer.TableSkewCostFunction</a>
+<pre>static class <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.html#line.1265">StochasticLoadBalancer.TableSkewCostFunction</a>
 extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CostFunction.html" title="class in org.apache.hadoop.hbase.master.balancer">StochasticLoadBalancer.CostFunction</a></pre>
 <div class="block">Compute the cost of a potential cluster configuration based upon how evenly
  distributed tables are.</div>
@@ -226,7 +226,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/Stoch
 <ul class="blockList">
 <li class="blockList">
 <h4>TABLE_SKEW_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/StochasticLoadBalancer.TableSkewCostFunction.html#line.1265">TABLE_SKEW_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/StochasticLoadBalancer.TableSkewCostFunction.html#line.1267">TABLE_SKEW_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.StochasticLoadBalancer.TableSkewCostFunction.TABLE_SKEW_COST_KEY">Constant Field Values</a></dd>
@@ -239,7 +239,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/Stoch
 <ul class="blockListLast">
 <li class="blockList">
 <h4>DEFAULT_TABLE_SKEW_COST</h4>
-<pre>private static final&nbsp;float <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.TableSkewCostFunction.html#line.1267">DEFAULT_TABLE_SKEW_COST</a></pre>
+<pre>private static final&nbsp;float <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.TableSkewCostFunction.html#line.1269">DEFAULT_TABLE_SKEW_COST</a></pre>
 <dl>
 <dt><span class="seeLabel">See Also:</span></dt>
 <dd><a href="../../../../../../constant-values.html#org.apache.hadoop.hbase.master.balancer.StochasticLoadBalancer.TableSkewCostFunction.DEFAULT_TABLE_SKEW_COST">Constant Field Values</a></dd>
@@ -260,7 +260,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/Stoch
 <ul class="blockListLast">
 <li class="blockList">
 <h4>TableSkewCostFunction</h4>
-<pre><a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.TableSkewCostFunction.html#line.1269">TableSkewCostFunction</a>(org.apache.hadoop.conf.Configuration&nbsp;conf)</pre>
+<pre><a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.TableSkewCostFunction.html#line.1271">TableSkewCostFunction</a>(org.apache.hadoop.conf.Configuration&nbsp;conf)</pre>
 </li>
 </ul>
 </li>
@@ -277,7 +277,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/Stoch
 <ul class="blockListLast">
 <li class="blockList">
 <h4>cost</h4>
-<pre>protected&nbsp;double&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.TableSkewCostFunction.html#line.1275">cost</a>()</pre>
+<pre>protected&nbsp;double&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.TableSkewCostFunction.html#line.1277">cost</a>()</pre>
 <dl>
 <dt><span class="overrideSpecifyLabel">Specified by:</span></dt>
 <dd><code><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CostFunction.html#cost--">cost</a></code>&nbsp;in class&nbsp;<code><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CostFunction.html" title="class in org.apache.hadoop.hbase.master.balancer">StochasticLoadBalancer.CostFunction</a></code></dd>
diff --git a/devapidocs/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.WriteRequestCostFunction.html b/devapidocs/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.WriteRequestCostFunction.html
index de66dc8..cf565a6 100644
--- a/devapidocs/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.WriteRequestCostFunction.html
+++ b/devapidocs/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.WriteRequestCostFunction.html
@@ -128,7 +128,7 @@ var activeTableTab = "activeTableTab";
 </dl>
 <hr>
 <br>
-<pre>static class <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.html#line.1555">StochasticLoadBalancer.WriteRequestCostFunction</a>
+<pre>static class <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.html#line.1557">StochasticLoadBalancer.WriteRequestCostFunction</a>
 extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CostFromRegionLoadAsRateFunction.html" title="class in org.apache.hadoop.hbase.master.balancer">StochasticLoadBalancer.CostFromRegionLoadAsRateFunction</a></pre>
 <div class="block">Compute the cost of total number of write requests.  The more unbalanced the higher the
  computed cost will be.  This uses a rolling average of regionload.</div>
@@ -250,7 +250,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/Stoch
 <ul class="blockList">
 <li class="blockList">
 <h4>WRITE_REQUEST_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/StochasticLoadBalancer.WriteRequestCostFunction.html#line.1557">WRITE_REQUEST_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/StochasticLoadBalancer.WriteRequestCostFunction.html#line.1559">WRITE_REQUEST_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.StochasticLoadBalancer.WriteRequestCostFunction.WRITE_REQUEST_COST_KEY">Constant Field Values</a></dd>
@@ -263,7 +263,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/Stoch
 <ul class="blockListLast">
 <li class="blockList">
 <h4>DEFAULT_WRITE_REQUEST_COST</h4>
-<pre>private static final&nbsp;float <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.WriteRequestCostFunction.html#line.1559">DEFAULT_WRITE_REQUEST_COST</a></pre>
+<pre>private static final&nbsp;float <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.WriteRequestCostFunction.html#line.1561">DEFAULT_WRITE_REQUEST_COST</a></pre>
 <dl>
 <dt><span class="seeLabel">See Also:</span></dt>
 <dd><a href="../../../../../../constant-values.html#org.apache.hadoop.hbase.master.balancer.StochasticLoadBalancer.WriteRequestCostFunction.DEFAULT_WRITE_REQUEST_COST">Constant Field Values</a></dd>
@@ -284,7 +284,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/Stoch
 <ul class="blockListLast">
 <li class="blockList">
 <h4>WriteRequestCostFunction</h4>
-<pre><a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.WriteRequestCostFunction.html#line.1561">WriteRequestCostFunction</a>(org.apache.hadoop.conf.Configuration&nbsp;conf)</pre>
+<pre><a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.WriteRequestCostFunction.html#line.1563">WriteRequestCostFunction</a>(org.apache.hadoop.conf.Configuration&nbsp;conf)</pre>
 </li>
 </ul>
 </li>
@@ -301,7 +301,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/Stoch
 <ul class="blockListLast">
 <li class="blockList">
 <h4>getCostFromRl</h4>
-<pre>protected&nbsp;double&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.WriteRequestCostFunction.html#line.1567">getCostFromRl</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BalancerRegionLoad.html" title="class in org.apache.hadoop.hbase.master.balancer">BalancerRegionLoad</a>&nbsp;rl)</pre>
+<pre>protected&nbsp;double&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.WriteRequestCostFunction.html#line.1569">getCostFromRl</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BalancerRegionLoad.html" title="class in org.apache.hadoop.hbase.master.balancer">BalancerRegionLoad</a>&nbsp;rl)</pre>
 <dl>
 <dt><span class="overrideSpecifyLabel">Specified by:</span></dt>
 <dd><code><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CostFromRegionLoadFunction.html#getCostFromRl-org.apache.hadoop.hbase.master.balancer.BalancerRegionLoad-">getCostFromRl</a></code>&nbsp;in class&nbsp;<code><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CostFromRegionLoadFunction.html" title="class in org.apache.hadoop.hbase.master.balancer">StochasticLoadBalancer.CostFromRegionLoadFunction</a></ [...]
diff --git a/devapidocs/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.html b/devapidocs/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.html
index 8a25218..a004a45 100644
--- a/devapidocs/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.html
+++ b/devapidocs/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.html
@@ -1159,7 +1159,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BaseL
 <ul class="blockList">
 <li class="blockList">
 <h4>balanceCluster</h4>
-<pre>public&nbsp;<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/master/RegionPlan.html" title="class in org.apache.hadoop.hbase.master">RegionPlan</a>&gt;&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.html#line.361">balanceCluster</a>(<a href="../../../../../../org/apache/hadoop/hbase/Tab [...]
+<pre>public&nbsp;<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/master/RegionPlan.html" title="class in org.apache.hadoop.hbase.master">RegionPlan</a>&gt;&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.html#line.363">balanceCluster</a>(<a href="../../../../../../org/apache/hadoop/hbase/Tab [...]
                                        <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/hbas [...]
 <div class="block"><span class="descfrmTypeLabel">Description copied from interface:&nbsp;<code><a href="../../../../../../org/apache/hadoop/hbase/master/LoadBalancer.html#balanceCluster-org.apache.hadoop.hbase.TableName-java.util.Map-">LoadBalancer</a></code></span></div>
 <div class="block">Perform the major balance operation</div>
@@ -1175,7 +1175,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BaseL
 <ul class="blockList">
 <li class="blockList">
 <h4>nextAction</h4>
-<pre><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BaseLoadBalancer.Cluster.Action.html" title="class in org.apache.hadoop.hbase.master.balancer">BaseLoadBalancer.Cluster.Action</a>&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.html#line.368">nextAction</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BaseLoadBalancer.Cluster.html" title="class in org.apache.hadoop.hbase.master.balancer"> [...]
+<pre><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BaseLoadBalancer.Cluster.Action.html" title="class in org.apache.hadoop.hbase.master.balancer">BaseLoadBalancer.Cluster.Action</a>&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.html#line.370">nextAction</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BaseLoadBalancer.Cluster.html" title="class in org.apache.hadoop.hbase.master.balancer"> [...]
 </li>
 </ul>
 <a name="balanceCluster-java.util.Map-">
@@ -1184,7 +1184,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BaseL
 <ul class="blockList">
 <li class="blockList">
 <h4>balanceCluster</h4>
-<pre>public&nbsp;<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/master/RegionPlan.html" title="class in org.apache.hadoop.hbase.master">RegionPlan</a>&gt;&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.html#line.378">balanceCluster</a>(<a href="https://docs.oracle.com/javase/8/docs/api/jav [...]
+<pre>public&nbsp;<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/master/RegionPlan.html" title="class in org.apache.hadoop.hbase.master">RegionPlan</a>&gt;&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.html#line.380">balanceCluster</a>(<a href="https://docs.oracle.com/javase/8/docs/api/jav [...]
 <div class="block">Given the cluster state this will try and approach an optimal balance. This
  should always approach the optimal state given enough steps.</div>
 <dl>
@@ -1199,7 +1199,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BaseL
 <ul class="blockList">
 <li class="blockList">
 <h4>updateStochasticCosts</h4>
-<pre>private&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.html#line.504">updateStochasticCosts</a>(<a href="../../../../../../org/apache/hadoop/hbase/TableName.html" title="class in org.apache.hadoop.hbase">TableName</a>&nbsp;tableName,
+<pre>private&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.html#line.506">updateStochasticCosts</a>(<a href="../../../../../../org/apache/hadoop/hbase/TableName.html" title="class in org.apache.hadoop.hbase">TableName</a>&nbsp;tableName,
                                    <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Double.html?is-external=true" title="class or interface in java.lang">Double</a>&nbsp;overall,
                                    <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Double.html?is-external=true" title="class or interface in java.lang">Double</a>[]&nbsp;subCosts)</pre>
 <div class="block">update costs to JMX</div>
@@ -1211,7 +1211,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BaseL
 <ul class="blockList">
 <li class="blockList">
 <h4>functionCost</h4>
-<pre>private&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/StochasticLoadBalancer.html#line.526">functionCost</a>()</pre>
+<pre>private&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/StochasticLoadBalancer.html#line.528">functionCost</a>()</pre>
 </li>
 </ul>
 <a name="createRegionPlans-org.apache.hadoop.hbase.master.balancer.BaseLoadBalancer.Cluster-">
@@ -1220,7 +1220,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BaseL
 <ul class="blockList">
 <li class="blockList">
 <h4>createRegionPlans</h4>
-<pre>private&nbsp;<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/master/RegionPlan.html" title="class in org.apache.hadoop.hbase.master">RegionPlan</a>&gt;&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.html#line.546">createRegionPlans</a>(<a href="../../../../../../org/apache/hadoop/hbase [...]
+<pre>private&nbsp;<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/master/RegionPlan.html" title="class in org.apache.hadoop.hbase.master">RegionPlan</a>&gt;&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.html#line.548">createRegionPlans</a>(<a href="../../../../../../org/apache/hadoop/hbase [...]
 <div class="block">Create all of the RegionPlan's needed to move from the initial cluster state to the desired
  state.</div>
 <dl>
@@ -1237,7 +1237,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BaseL
 <ul class="blockList">
 <li class="blockList">
 <h4>updateRegionLoad</h4>
-<pre>private&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.html#line.572">updateRegionLoad</a>()</pre>
+<pre>private&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.html#line.574">updateRegionLoad</a>()</pre>
 <div class="block">Store the current region loads.</div>
 </li>
 </ul>
@@ -1247,7 +1247,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BaseL
 <ul class="blockList">
 <li class="blockList">
 <h4>initCosts</h4>
-<pre>protected&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.html#line.597">initCosts</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BaseLoadBalancer.Cluster.html" title="class in org.apache.hadoop.hbase.master.balancer">BaseLoadBalancer.Cluster</a>&nbsp;cluster)</pre>
+<pre>protected&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.html#line.599">initCosts</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BaseLoadBalancer.Cluster.html" title="class in org.apache.hadoop.hbase.master.balancer">BaseLoadBalancer.Cluster</a>&nbsp;cluster)</pre>
 </li>
 </ul>
 <a name="updateCostsWithAction-org.apache.hadoop.hbase.master.balancer.BaseLoadBalancer.Cluster-org.apache.hadoop.hbase.master.balancer.BaseLoadBalancer.Cluster.Action-">
@@ -1256,7 +1256,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BaseL
 <ul class="blockList">
 <li class="blockList">
 <h4>updateCostsWithAction</h4>
-<pre>protected&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.html#line.603">updateCostsWithAction</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BaseLoadBalancer.Cluster.html" title="class in org.apache.hadoop.hbase.master.balancer">BaseLoadBalancer.Cluster</a>&nbsp;cluster,
+<pre>protected&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.html#line.605">updateCostsWithAction</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BaseLoadBalancer.Cluster.html" title="class in org.apache.hadoop.hbase.master.balancer">BaseLoadBalancer.Cluster</a>&nbsp;cluster,
                                      <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BaseLoadBalancer.Cluster.Action.html" title="class in org.apache.hadoop.hbase.master.balancer">BaseLoadBalancer.Cluster.Action</a>&nbsp;action)</pre>
 </li>
 </ul>
@@ -1266,7 +1266,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BaseL
 <ul class="blockList">
 <li class="blockList">
 <h4>getCostFunctionNames</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/StochasticLoadBalancer.html#line.612">getCostFunctionNames</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/StochasticLoadBalancer.html#line.614">getCostFunctionNames</a>()</pre>
 <div class="block">Get the names of the cost functions</div>
 </li>
 </ul>
@@ -1276,7 +1276,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BaseL
 <ul class="blockList">
 <li class="blockList">
 <h4>computeCost</h4>
-<pre>protected&nbsp;double&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.html#line.632">computeCost</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BaseLoadBalancer.Cluster.html" title="class in org.apache.hadoop.hbase.master.balancer">BaseLoadBalancer.Cluster</a>&nbsp;cluster,
+<pre>protected&nbsp;double&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.html#line.634">computeCost</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BaseLoadBalancer.Cluster.html" title="class in org.apache.hadoop.hbase.master.balancer">BaseLoadBalancer.Cluster</a>&nbsp;cluster,
                              double&nbsp;previousCost)</pre>
 <div class="block">This is the main cost function.  It will compute a cost associated with a proposed cluster
  state.  All different costs will be combined with their multipliers to produce a double cost.</div>
@@ -1296,7 +1296,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BaseL
 <ul class="blockListLast">
 <li class="blockList">
 <h4>composeAttributeName</h4>
-<pre>public static&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/StochasticLoadBalancer.html#line.1779">composeAttributeName</a>(<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;tableName,
+<pre>public static&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/StochasticLoadBalancer.html#line.1781">composeAttributeName</a>(<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;tableName,
                                           <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;costFunctionName)</pre>
 <div class="block">A helper function to compose the attribute name from tablename and costfunction name</div>
 </li>
diff --git a/devapidocs/src-html/org/apache/hadoop/hbase/Version.html b/devapidocs/src-html/org/apache/hadoop/hbase/Version.html
index b6b3a87..dc53687 100644
--- a/devapidocs/src-html/org/apache/hadoop/hbase/Version.html
+++ b/devapidocs/src-html/org/apache/hadoop/hbase/Version.html
@@ -16,9 +16,9 @@
 <span class="sourceLineNo">008</span>@InterfaceAudience.Private<a name="line.8"></a>
 <span class="sourceLineNo">009</span>public class Version {<a name="line.9"></a>
 <span class="sourceLineNo">010</span>  public static final String version = "3.0.0-SNAPSHOT";<a name="line.10"></a>
-<span class="sourceLineNo">011</span>  public static final String revision = "800c35a30e647ee6a87bab67b528e2634b38d0c4";<a name="line.11"></a>
+<span class="sourceLineNo">011</span>  public static final String revision = "f69e7705e075df0744bde61cc29682468f2e431f";<a name="line.11"></a>
 <span class="sourceLineNo">012</span>  public static final String user = "jenkins";<a name="line.12"></a>
-<span class="sourceLineNo">013</span>  public static final String date = "Fri Oct  4 14:35:04 UTC 2019";<a name="line.13"></a>
+<span class="sourceLineNo">013</span>  public static final String date = "Sat Oct  5 14:36:31 UTC 2019";<a name="line.13"></a>
 <span class="sourceLineNo">014</span>  public static final String url = "git://jenkins-websites-he-de.apache.org/home/jenkins/jenkins-slave/workspace/hbase_generate_website/hbase";<a name="line.14"></a>
 <span class="sourceLineNo">015</span>  public static final String srcChecksum = "(stdin)=";<a name="line.15"></a>
 <span class="sourceLineNo">016</span>}<a name="line.16"></a>
diff --git a/devapidocs/src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CPRequestCostFunction.html b/devapidocs/src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CPRequestCostFunction.html
index 4a9d7eb..7ce29c3 100644
--- a/devapidocs/src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CPRequestCostFunction.html
+++ b/devapidocs/src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CPRequestCostFunction.html
@@ -356,1438 +356,1440 @@
 <span class="sourceLineNo">348</span>    if (total &lt;= 0 || sumMultiplier &lt;= 0<a name="line.348"></a>
 <span class="sourceLineNo">349</span>        || (sumMultiplier &gt; 0 &amp;&amp; (total / sumMultiplier) &lt; minCostNeedBalance)) {<a name="line.349"></a>
 <span class="sourceLineNo">350</span>      if (LOG.isTraceEnabled()) {<a name="line.350"></a>
-<span class="sourceLineNo">351</span>        LOG.trace("Skipping load balancing because balanced cluster; " + "total cost is " + total<a name="line.351"></a>
-<span class="sourceLineNo">352</span>          + ", sum multiplier is " + sumMultiplier + " min cost which need balance is "<a name="line.352"></a>
-<span class="sourceLineNo">353</span>          + minCostNeedBalance);<a name="line.353"></a>
-<span class="sourceLineNo">354</span>      }<a name="line.354"></a>
-<span class="sourceLineNo">355</span>      return false;<a name="line.355"></a>
-<span class="sourceLineNo">356</span>    }<a name="line.356"></a>
-<span class="sourceLineNo">357</span>    return true;<a name="line.357"></a>
-<span class="sourceLineNo">358</span>  }<a name="line.358"></a>
-<span class="sourceLineNo">359</span><a name="line.359"></a>
-<span class="sourceLineNo">360</span>  @Override<a name="line.360"></a>
-<span class="sourceLineNo">361</span>  public synchronized List&lt;RegionPlan&gt; balanceCluster(TableName tableName, Map&lt;ServerName,<a name="line.361"></a>
-<span class="sourceLineNo">362</span>    List&lt;RegionInfo&gt;&gt; clusterState) {<a name="line.362"></a>
-<span class="sourceLineNo">363</span>    this.tableName = tableName;<a name="line.363"></a>
-<span class="sourceLineNo">364</span>    return balanceCluster(clusterState);<a name="line.364"></a>
-<span class="sourceLineNo">365</span>  }<a name="line.365"></a>
-<span class="sourceLineNo">366</span><a name="line.366"></a>
-<span class="sourceLineNo">367</span>  @VisibleForTesting<a name="line.367"></a>
-<span class="sourceLineNo">368</span>  Cluster.Action nextAction(Cluster cluster) {<a name="line.368"></a>
-<span class="sourceLineNo">369</span>    return candidateGenerators.get(RANDOM.nextInt(candidateGenerators.size()))<a name="line.369"></a>
-<span class="sourceLineNo">370</span>            .generate(cluster);<a name="line.370"></a>
-<span class="sourceLineNo">371</span>  }<a name="line.371"></a>
-<span class="sourceLineNo">372</span><a name="line.372"></a>
-<span class="sourceLineNo">373</span>  /**<a name="line.373"></a>
-<span class="sourceLineNo">374</span>   * Given the cluster state this will try and approach an optimal balance. This<a name="line.374"></a>
-<span class="sourceLineNo">375</span>   * should always approach the optimal state given enough steps.<a name="line.375"></a>
-<span class="sourceLineNo">376</span>   */<a name="line.376"></a>
-<span class="sourceLineNo">377</span>  @Override<a name="line.377"></a>
-<span class="sourceLineNo">378</span>  public synchronized List&lt;RegionPlan&gt; balanceCluster(Map&lt;ServerName,<a name="line.378"></a>
-<span class="sourceLineNo">379</span>    List&lt;RegionInfo&gt;&gt; clusterState) {<a name="line.379"></a>
-<span class="sourceLineNo">380</span>    List&lt;RegionPlan&gt; plans = balanceMasterRegions(clusterState);<a name="line.380"></a>
-<span class="sourceLineNo">381</span>    if (plans != null || clusterState == null || clusterState.size() &lt;= 1) {<a name="line.381"></a>
-<span class="sourceLineNo">382</span>      return plans;<a name="line.382"></a>
-<span class="sourceLineNo">383</span>    }<a name="line.383"></a>
-<span class="sourceLineNo">384</span><a name="line.384"></a>
-<span class="sourceLineNo">385</span>    if (masterServerName != null &amp;&amp; clusterState.containsKey(masterServerName)) {<a name="line.385"></a>
-<span class="sourceLineNo">386</span>      if (clusterState.size() &lt;= 2) {<a name="line.386"></a>
-<span class="sourceLineNo">387</span>        return null;<a name="line.387"></a>
-<span class="sourceLineNo">388</span>      }<a name="line.388"></a>
-<span class="sourceLineNo">389</span>      clusterState = new HashMap&lt;&gt;(clusterState);<a name="line.389"></a>
-<span class="sourceLineNo">390</span>      clusterState.remove(masterServerName);<a name="line.390"></a>
-<span class="sourceLineNo">391</span>    }<a name="line.391"></a>
-<span class="sourceLineNo">392</span><a name="line.392"></a>
-<span class="sourceLineNo">393</span>    // On clusters with lots of HFileLinks or lots of reference files,<a name="line.393"></a>
-<span class="sourceLineNo">394</span>    // instantiating the storefile infos can be quite expensive.<a name="line.394"></a>
-<span class="sourceLineNo">395</span>    // Allow turning this feature off if the locality cost is not going to<a name="line.395"></a>
-<span class="sourceLineNo">396</span>    // be used in any computations.<a name="line.396"></a>
-<span class="sourceLineNo">397</span>    RegionLocationFinder finder = null;<a name="line.397"></a>
-<span class="sourceLineNo">398</span>    if ((this.localityCost != null &amp;&amp; this.localityCost.getMultiplier() &gt; 0)<a name="line.398"></a>
-<span class="sourceLineNo">399</span>        || (this.rackLocalityCost != null &amp;&amp; this.rackLocalityCost.getMultiplier() &gt; 0)) {<a name="line.399"></a>
-<span class="sourceLineNo">400</span>      finder = this.regionFinder;<a name="line.400"></a>
-<span class="sourceLineNo">401</span>    }<a name="line.401"></a>
-<span class="sourceLineNo">402</span><a name="line.402"></a>
-<span class="sourceLineNo">403</span>    //The clusterState that is given to this method contains the state<a name="line.403"></a>
-<span class="sourceLineNo">404</span>    //of all the regions in the table(s) (that's true today)<a name="line.404"></a>
-<span class="sourceLineNo">405</span>    // Keep track of servers to iterate through them.<a name="line.405"></a>
-<span class="sourceLineNo">406</span>    Cluster cluster = new Cluster(clusterState, loads, finder, rackManager);<a name="line.406"></a>
-<span class="sourceLineNo">407</span><a name="line.407"></a>
-<span class="sourceLineNo">408</span>    long startTime = EnvironmentEdgeManager.currentTime();<a name="line.408"></a>
+<span class="sourceLineNo">351</span>        final String loadBalanceTarget =<a name="line.351"></a>
+<span class="sourceLineNo">352</span>            isByTable ? String.format("table (%s)", tableName) : "cluster";<a name="line.352"></a>
+<span class="sourceLineNo">353</span>        LOG.trace("Skipping load balancing because the {} is balanced. Total cost: {}, "<a name="line.353"></a>
+<span class="sourceLineNo">354</span>            + "Sum multiplier: {}, Minimum cost needed for balance: {}", loadBalanceTarget, total,<a name="line.354"></a>
+<span class="sourceLineNo">355</span>            sumMultiplier, minCostNeedBalance);<a name="line.355"></a>
+<span class="sourceLineNo">356</span>      }<a name="line.356"></a>
+<span class="sourceLineNo">357</span>      return false;<a name="line.357"></a>
+<span class="sourceLineNo">358</span>    }<a name="line.358"></a>
+<span class="sourceLineNo">359</span>    return true;<a name="line.359"></a>
+<span class="sourceLineNo">360</span>  }<a name="line.360"></a>
+<span class="sourceLineNo">361</span><a name="line.361"></a>
+<span class="sourceLineNo">362</span>  @Override<a name="line.362"></a>
+<span class="sourceLineNo">363</span>  public synchronized List&lt;RegionPlan&gt; balanceCluster(TableName tableName, Map&lt;ServerName,<a name="line.363"></a>
+<span class="sourceLineNo">364</span>    List&lt;RegionInfo&gt;&gt; clusterState) {<a name="line.364"></a>
+<span class="sourceLineNo">365</span>    this.tableName = tableName;<a name="line.365"></a>
+<span class="sourceLineNo">366</span>    return balanceCluster(clusterState);<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>  @VisibleForTesting<a name="line.369"></a>
+<span class="sourceLineNo">370</span>  Cluster.Action nextAction(Cluster cluster) {<a name="line.370"></a>
+<span class="sourceLineNo">371</span>    return candidateGenerators.get(RANDOM.nextInt(candidateGenerators.size()))<a name="line.371"></a>
+<span class="sourceLineNo">372</span>            .generate(cluster);<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>  /**<a name="line.375"></a>
+<span class="sourceLineNo">376</span>   * Given the cluster state this will try and approach an optimal balance. This<a name="line.376"></a>
+<span class="sourceLineNo">377</span>   * should always approach the optimal state given enough steps.<a name="line.377"></a>
+<span class="sourceLineNo">378</span>   */<a name="line.378"></a>
+<span class="sourceLineNo">379</span>  @Override<a name="line.379"></a>
+<span class="sourceLineNo">380</span>  public synchronized List&lt;RegionPlan&gt; balanceCluster(Map&lt;ServerName,<a name="line.380"></a>
+<span class="sourceLineNo">381</span>    List&lt;RegionInfo&gt;&gt; clusterState) {<a name="line.381"></a>
+<span class="sourceLineNo">382</span>    List&lt;RegionPlan&gt; plans = balanceMasterRegions(clusterState);<a name="line.382"></a>
+<span class="sourceLineNo">383</span>    if (plans != null || clusterState == null || clusterState.size() &lt;= 1) {<a name="line.383"></a>
+<span class="sourceLineNo">384</span>      return plans;<a name="line.384"></a>
+<span class="sourceLineNo">385</span>    }<a name="line.385"></a>
+<span class="sourceLineNo">386</span><a name="line.386"></a>
+<span class="sourceLineNo">387</span>    if (masterServerName != null &amp;&amp; clusterState.containsKey(masterServerName)) {<a name="line.387"></a>
+<span class="sourceLineNo">388</span>      if (clusterState.size() &lt;= 2) {<a name="line.388"></a>
+<span class="sourceLineNo">389</span>        return null;<a name="line.389"></a>
+<span class="sourceLineNo">390</span>      }<a name="line.390"></a>
+<span class="sourceLineNo">391</span>      clusterState = new HashMap&lt;&gt;(clusterState);<a name="line.391"></a>
+<span class="sourceLineNo">392</span>      clusterState.remove(masterServerName);<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>    // On clusters with lots of HFileLinks or lots of reference files,<a name="line.395"></a>
+<span class="sourceLineNo">396</span>    // instantiating the storefile infos can be quite expensive.<a name="line.396"></a>
+<span class="sourceLineNo">397</span>    // Allow turning this feature off if the locality cost is not going to<a name="line.397"></a>
+<span class="sourceLineNo">398</span>    // be used in any computations.<a name="line.398"></a>
+<span class="sourceLineNo">399</span>    RegionLocationFinder finder = null;<a name="line.399"></a>
+<span class="sourceLineNo">400</span>    if ((this.localityCost != null &amp;&amp; this.localityCost.getMultiplier() &gt; 0)<a name="line.400"></a>
+<span class="sourceLineNo">401</span>        || (this.rackLocalityCost != null &amp;&amp; this.rackLocalityCost.getMultiplier() &gt; 0)) {<a name="line.401"></a>
+<span class="sourceLineNo">402</span>      finder = this.regionFinder;<a name="line.402"></a>
+<span class="sourceLineNo">403</span>    }<a name="line.403"></a>
+<span class="sourceLineNo">404</span><a name="line.404"></a>
+<span class="sourceLineNo">405</span>    //The clusterState that is given to this method contains the state<a name="line.405"></a>
+<span class="sourceLineNo">406</span>    //of all the regions in the table(s) (that's true today)<a name="line.406"></a>
+<span class="sourceLineNo">407</span>    // Keep track of servers to iterate through them.<a name="line.407"></a>
+<span class="sourceLineNo">408</span>    Cluster cluster = new Cluster(clusterState, loads, finder, rackManager);<a name="line.408"></a>
 <span class="sourceLineNo">409</span><a name="line.409"></a>
-<span class="sourceLineNo">410</span>    initCosts(cluster);<a name="line.410"></a>
+<span class="sourceLineNo">410</span>    long startTime = EnvironmentEdgeManager.currentTime();<a name="line.410"></a>
 <span class="sourceLineNo">411</span><a name="line.411"></a>
-<span class="sourceLineNo">412</span>    if (!needsBalance(cluster)) {<a name="line.412"></a>
-<span class="sourceLineNo">413</span>      return null;<a name="line.413"></a>
-<span class="sourceLineNo">414</span>    }<a name="line.414"></a>
-<span class="sourceLineNo">415</span><a name="line.415"></a>
-<span class="sourceLineNo">416</span>    double currentCost = computeCost(cluster, Double.MAX_VALUE);<a name="line.416"></a>
-<span class="sourceLineNo">417</span>    curOverallCost = currentCost;<a name="line.417"></a>
-<span class="sourceLineNo">418</span>    for (int i = 0; i &lt; this.curFunctionCosts.length; i++) {<a name="line.418"></a>
-<span class="sourceLineNo">419</span>      curFunctionCosts[i] = tempFunctionCosts[i];<a name="line.419"></a>
-<span class="sourceLineNo">420</span>    }<a name="line.420"></a>
-<span class="sourceLineNo">421</span>    double initCost = currentCost;<a name="line.421"></a>
-<span class="sourceLineNo">422</span>    double newCost = currentCost;<a name="line.422"></a>
-<span class="sourceLineNo">423</span><a name="line.423"></a>
-<span class="sourceLineNo">424</span>    long computedMaxSteps;<a name="line.424"></a>
-<span class="sourceLineNo">425</span>    if (runMaxSteps) {<a name="line.425"></a>
-<span class="sourceLineNo">426</span>      computedMaxSteps = Math.max(this.maxSteps,<a name="line.426"></a>
-<span class="sourceLineNo">427</span>          ((long)cluster.numRegions * (long)this.stepsPerRegion * (long)cluster.numServers));<a name="line.427"></a>
-<span class="sourceLineNo">428</span>    } else {<a name="line.428"></a>
-<span class="sourceLineNo">429</span>      long calculatedMaxSteps = (long)cluster.numRegions * (long)this.stepsPerRegion *<a name="line.429"></a>
-<span class="sourceLineNo">430</span>          (long)cluster.numServers;<a name="line.430"></a>
-<span class="sourceLineNo">431</span>      computedMaxSteps = Math.min(this.maxSteps, calculatedMaxSteps);<a name="line.431"></a>
-<span class="sourceLineNo">432</span>      if (calculatedMaxSteps &gt; maxSteps) {<a name="line.432"></a>
-<span class="sourceLineNo">433</span>        LOG.warn("calculatedMaxSteps:{} for loadbalancer's stochastic walk is larger than "<a name="line.433"></a>
-<span class="sourceLineNo">434</span>            + "maxSteps:{}. Hence load balancing may not work well. Setting parameter "<a name="line.434"></a>
-<span class="sourceLineNo">435</span>            + "\"hbase.master.balancer.stochastic.runMaxSteps\" to true can overcome this issue."<a name="line.435"></a>
-<span class="sourceLineNo">436</span>            + "(This config change does not require service restart)", calculatedMaxSteps,<a name="line.436"></a>
-<span class="sourceLineNo">437</span>            maxSteps);<a name="line.437"></a>
-<span class="sourceLineNo">438</span>      }<a name="line.438"></a>
-<span class="sourceLineNo">439</span>    }<a name="line.439"></a>
-<span class="sourceLineNo">440</span>    LOG.info("start StochasticLoadBalancer.balancer, initCost=" + currentCost + ", functionCost="<a name="line.440"></a>
-<span class="sourceLineNo">441</span>        + functionCost() + " computedMaxSteps: " + computedMaxSteps);<a name="line.441"></a>
-<span class="sourceLineNo">442</span><a name="line.442"></a>
-<span class="sourceLineNo">443</span>    // Perform a stochastic walk to see if we can get a good fit.<a name="line.443"></a>
-<span class="sourceLineNo">444</span>    long step;<a name="line.444"></a>
-<span class="sourceLineNo">445</span><a name="line.445"></a>
-<span class="sourceLineNo">446</span>    for (step = 0; step &lt; computedMaxSteps; step++) {<a name="line.446"></a>
-<span class="sourceLineNo">447</span>      Cluster.Action action = nextAction(cluster);<a name="line.447"></a>
-<span class="sourceLineNo">448</span><a name="line.448"></a>
-<span class="sourceLineNo">449</span>      if (action.type == Type.NULL) {<a name="line.449"></a>
-<span class="sourceLineNo">450</span>        continue;<a name="line.450"></a>
-<span class="sourceLineNo">451</span>      }<a name="line.451"></a>
-<span class="sourceLineNo">452</span><a name="line.452"></a>
-<span class="sourceLineNo">453</span>      cluster.doAction(action);<a name="line.453"></a>
-<span class="sourceLineNo">454</span>      updateCostsWithAction(cluster, action);<a name="line.454"></a>
-<span class="sourceLineNo">455</span><a name="line.455"></a>
-<span class="sourceLineNo">456</span>      newCost = computeCost(cluster, currentCost);<a name="line.456"></a>
+<span class="sourceLineNo">412</span>    initCosts(cluster);<a name="line.412"></a>
+<span class="sourceLineNo">413</span><a name="line.413"></a>
+<span class="sourceLineNo">414</span>    if (!needsBalance(cluster)) {<a name="line.414"></a>
+<span class="sourceLineNo">415</span>      return null;<a name="line.415"></a>
+<span class="sourceLineNo">416</span>    }<a name="line.416"></a>
+<span class="sourceLineNo">417</span><a name="line.417"></a>
+<span class="sourceLineNo">418</span>    double currentCost = computeCost(cluster, Double.MAX_VALUE);<a name="line.418"></a>
+<span class="sourceLineNo">419</span>    curOverallCost = currentCost;<a name="line.419"></a>
+<span class="sourceLineNo">420</span>    for (int i = 0; i &lt; this.curFunctionCosts.length; i++) {<a name="line.420"></a>
+<span class="sourceLineNo">421</span>      curFunctionCosts[i] = tempFunctionCosts[i];<a name="line.421"></a>
+<span class="sourceLineNo">422</span>    }<a name="line.422"></a>
+<span class="sourceLineNo">423</span>    double initCost = currentCost;<a name="line.423"></a>
+<span class="sourceLineNo">424</span>    double newCost = currentCost;<a name="line.424"></a>
+<span class="sourceLineNo">425</span><a name="line.425"></a>
+<span class="sourceLineNo">426</span>    long computedMaxSteps;<a name="line.426"></a>
+<span class="sourceLineNo">427</span>    if (runMaxSteps) {<a name="line.427"></a>
+<span class="sourceLineNo">428</span>      computedMaxSteps = Math.max(this.maxSteps,<a name="line.428"></a>
+<span class="sourceLineNo">429</span>          ((long)cluster.numRegions * (long)this.stepsPerRegion * (long)cluster.numServers));<a name="line.429"></a>
+<span class="sourceLineNo">430</span>    } else {<a name="line.430"></a>
+<span class="sourceLineNo">431</span>      long calculatedMaxSteps = (long)cluster.numRegions * (long)this.stepsPerRegion *<a name="line.431"></a>
+<span class="sourceLineNo">432</span>          (long)cluster.numServers;<a name="line.432"></a>
+<span class="sourceLineNo">433</span>      computedMaxSteps = Math.min(this.maxSteps, calculatedMaxSteps);<a name="line.433"></a>
+<span class="sourceLineNo">434</span>      if (calculatedMaxSteps &gt; maxSteps) {<a name="line.434"></a>
+<span class="sourceLineNo">435</span>        LOG.warn("calculatedMaxSteps:{} for loadbalancer's stochastic walk is larger than "<a name="line.435"></a>
+<span class="sourceLineNo">436</span>            + "maxSteps:{}. Hence load balancing may not work well. Setting parameter "<a name="line.436"></a>
+<span class="sourceLineNo">437</span>            + "\"hbase.master.balancer.stochastic.runMaxSteps\" to true can overcome this issue."<a name="line.437"></a>
+<span class="sourceLineNo">438</span>            + "(This config change does not require service restart)", calculatedMaxSteps,<a name="line.438"></a>
+<span class="sourceLineNo">439</span>            maxSteps);<a name="line.439"></a>
+<span class="sourceLineNo">440</span>      }<a name="line.440"></a>
+<span class="sourceLineNo">441</span>    }<a name="line.441"></a>
+<span class="sourceLineNo">442</span>    LOG.info("start StochasticLoadBalancer.balancer, initCost=" + currentCost + ", functionCost="<a name="line.442"></a>
+<span class="sourceLineNo">443</span>        + functionCost() + " computedMaxSteps: " + computedMaxSteps);<a name="line.443"></a>
+<span class="sourceLineNo">444</span><a name="line.444"></a>
+<span class="sourceLineNo">445</span>    // Perform a stochastic walk to see if we can get a good fit.<a name="line.445"></a>
+<span class="sourceLineNo">446</span>    long step;<a name="line.446"></a>
+<span class="sourceLineNo">447</span><a name="line.447"></a>
+<span class="sourceLineNo">448</span>    for (step = 0; step &lt; computedMaxSteps; step++) {<a name="line.448"></a>
+<span class="sourceLineNo">449</span>      Cluster.Action action = nextAction(cluster);<a name="line.449"></a>
+<span class="sourceLineNo">450</span><a name="line.450"></a>
+<span class="sourceLineNo">451</span>      if (action.type == Type.NULL) {<a name="line.451"></a>
+<span class="sourceLineNo">452</span>        continue;<a name="line.452"></a>
+<span class="sourceLineNo">453</span>      }<a name="line.453"></a>
+<span class="sourceLineNo">454</span><a name="line.454"></a>
+<span class="sourceLineNo">455</span>      cluster.doAction(action);<a name="line.455"></a>
+<span class="sourceLineNo">456</span>      updateCostsWithAction(cluster, action);<a name="line.456"></a>
 <span class="sourceLineNo">457</span><a name="line.457"></a>
-<span class="sourceLineNo">458</span>      // Should this be kept?<a name="line.458"></a>
-<span class="sourceLineNo">459</span>      if (newCost &lt; currentCost) {<a name="line.459"></a>
-<span class="sourceLineNo">460</span>        currentCost = newCost;<a name="line.460"></a>
-<span class="sourceLineNo">461</span><a name="line.461"></a>
-<span class="sourceLineNo">462</span>        // save for JMX<a name="line.462"></a>
-<span class="sourceLineNo">463</span>        curOverallCost = currentCost;<a name="line.463"></a>
-<span class="sourceLineNo">464</span>        for (int i = 0; i &lt; this.curFunctionCosts.length; i++) {<a name="line.464"></a>
-<span class="sourceLineNo">465</span>          curFunctionCosts[i] = tempFunctionCosts[i];<a name="line.465"></a>
-<span class="sourceLineNo">466</span>        }<a name="line.466"></a>
-<span class="sourceLineNo">467</span>      } else {<a name="line.467"></a>
-<span class="sourceLineNo">468</span>        // Put things back the way they were before.<a name="line.468"></a>
-<span class="sourceLineNo">469</span>        // TODO: undo by remembering old values<a name="line.469"></a>
-<span class="sourceLineNo">470</span>        Action undoAction = action.undoAction();<a name="line.470"></a>
-<span class="sourceLineNo">471</span>        cluster.doAction(undoAction);<a name="line.471"></a>
-<span class="sourceLineNo">472</span>        updateCostsWithAction(cluster, undoAction);<a name="line.472"></a>
-<span class="sourceLineNo">473</span>      }<a name="line.473"></a>
-<span class="sourceLineNo">474</span><a name="line.474"></a>
-<span class="sourceLineNo">475</span>      if (EnvironmentEdgeManager.currentTime() - startTime &gt;<a name="line.475"></a>
-<span class="sourceLineNo">476</span>          maxRunningTime) {<a name="line.476"></a>
-<span class="sourceLineNo">477</span>        break;<a name="line.477"></a>
-<span class="sourceLineNo">478</span>      }<a name="line.478"></a>
-<span class="sourceLineNo">479</span>    }<a name="line.479"></a>
-<span class="sourceLineNo">480</span>    long endTime = EnvironmentEdgeManager.currentTime();<a name="line.480"></a>
-<span class="sourceLineNo">481</span><a name="line.481"></a>
-<span class="sourceLineNo">482</span>    metricsBalancer.balanceCluster(endTime - startTime);<a name="line.482"></a>
+<span class="sourceLineNo">458</span>      newCost = computeCost(cluster, currentCost);<a name="line.458"></a>
+<span class="sourceLineNo">459</span><a name="line.459"></a>
+<span class="sourceLineNo">460</span>      // Should this be kept?<a name="line.460"></a>
+<span class="sourceLineNo">461</span>      if (newCost &lt; currentCost) {<a name="line.461"></a>
+<span class="sourceLineNo">462</span>        currentCost = newCost;<a name="line.462"></a>
+<span class="sourceLineNo">463</span><a name="line.463"></a>
+<span class="sourceLineNo">464</span>        // save for JMX<a name="line.464"></a>
+<span class="sourceLineNo">465</span>        curOverallCost = currentCost;<a name="line.465"></a>
+<span class="sourceLineNo">466</span>        for (int i = 0; i &lt; this.curFunctionCosts.length; i++) {<a name="line.466"></a>
+<span class="sourceLineNo">467</span>          curFunctionCosts[i] = tempFunctionCosts[i];<a name="line.467"></a>
+<span class="sourceLineNo">468</span>        }<a name="line.468"></a>
+<span class="sourceLineNo">469</span>      } else {<a name="line.469"></a>
+<span class="sourceLineNo">470</span>        // Put things back the way they were before.<a name="line.470"></a>
+<span class="sourceLineNo">471</span>        // TODO: undo by remembering old values<a name="line.471"></a>
+<span class="sourceLineNo">472</span>        Action undoAction = action.undoAction();<a name="line.472"></a>
+<span class="sourceLineNo">473</span>        cluster.doAction(undoAction);<a name="line.473"></a>
+<span class="sourceLineNo">474</span>        updateCostsWithAction(cluster, undoAction);<a name="line.474"></a>
+<span class="sourceLineNo">475</span>      }<a name="line.475"></a>
+<span class="sourceLineNo">476</span><a name="line.476"></a>
+<span class="sourceLineNo">477</span>      if (EnvironmentEdgeManager.currentTime() - startTime &gt;<a name="line.477"></a>
+<span class="sourceLineNo">478</span>          maxRunningTime) {<a name="line.478"></a>
+<span class="sourceLineNo">479</span>        break;<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>    long endTime = EnvironmentEdgeManager.currentTime();<a name="line.482"></a>
 <span class="sourceLineNo">483</span><a name="line.483"></a>
-<span class="sourceLineNo">484</span>    // update costs metrics<a name="line.484"></a>
-<span class="sourceLineNo">485</span>    updateStochasticCosts(tableName, curOverallCost, curFunctionCosts);<a name="line.485"></a>
-<span class="sourceLineNo">486</span>    if (initCost &gt; currentCost) {<a name="line.486"></a>
-<span class="sourceLineNo">487</span>      plans = createRegionPlans(cluster);<a name="line.487"></a>
-<span class="sourceLineNo">488</span>      LOG.info("Finished computing new load balance plan. Computation took {}" +<a name="line.488"></a>
-<span class="sourceLineNo">489</span>        " to try {} different iterations.  Found a solution that moves " +<a name="line.489"></a>
-<span class="sourceLineNo">490</span>        "{} regions; Going from a computed cost of {}" +<a name="line.490"></a>
-<span class="sourceLineNo">491</span>        " to a new cost of {}", java.time.Duration.ofMillis(endTime - startTime),<a name="line.491"></a>
-<span class="sourceLineNo">492</span>        step, plans.size(), initCost, currentCost);<a name="line.492"></a>
-<span class="sourceLineNo">493</span>      return plans;<a name="line.493"></a>
-<span class="sourceLineNo">494</span>    }<a name="line.494"></a>
-<span class="sourceLineNo">495</span>    LOG.info("Could not find a better load balance plan.  Tried {} different configurations in " +<a name="line.495"></a>
-<span class="sourceLineNo">496</span>      "{}, and did not find anything with a computed cost less than {}", step,<a name="line.496"></a>
-<span class="sourceLineNo">497</span>      java.time.Duration.ofMillis(endTime - startTime), initCost);<a name="line.497"></a>
-<span class="sourceLineNo">498</span>    return null;<a name="line.498"></a>
-<span class="sourceLineNo">499</span>  }<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>   * update costs to JMX<a name="line.502"></a>
-<span class="sourceLineNo">503</span>   */<a name="line.503"></a>
-<span class="sourceLineNo">504</span>  private void updateStochasticCosts(TableName tableName, Double overall, Double[] subCosts) {<a name="line.504"></a>
-<span class="sourceLineNo">505</span>    if (tableName == null) return;<a name="line.505"></a>
-<span class="sourceLineNo">506</span><a name="line.506"></a>
-<span class="sourceLineNo">507</span>    // check if the metricsBalancer is MetricsStochasticBalancer before casting<a name="line.507"></a>
-<span class="sourceLineNo">508</span>    if (metricsBalancer instanceof MetricsStochasticBalancer) {<a name="line.508"></a>
-<span class="sourceLineNo">509</span>      MetricsStochasticBalancer balancer = (MetricsStochasticBalancer) metricsBalancer;<a name="line.509"></a>
-<span class="sourceLineNo">510</span>      // overall cost<a name="line.510"></a>
-<span class="sourceLineNo">511</span>      balancer.updateStochasticCost(tableName.getNameAsString(),<a name="line.511"></a>
-<span class="sourceLineNo">512</span>        "Overall", "Overall cost", overall);<a name="line.512"></a>
-<span class="sourceLineNo">513</span><a name="line.513"></a>
-<span class="sourceLineNo">514</span>      // each cost function<a name="line.514"></a>
-<span class="sourceLineNo">515</span>      for (int i = 0; i &lt; costFunctions.size(); i++) {<a name="line.515"></a>
-<span class="sourceLineNo">516</span>        CostFunction costFunction = costFunctions.get(i);<a name="line.516"></a>
-<span class="sourceLineNo">517</span>        String costFunctionName = costFunction.getClass().getSimpleName();<a name="line.517"></a>
-<span class="sourceLineNo">518</span>        Double costPercent = (overall == 0) ? 0 : (subCosts[i] / overall);<a name="line.518"></a>
-<span class="sourceLineNo">519</span>        // TODO: cost function may need a specific description<a name="line.519"></a>
-<span class="sourceLineNo">520</span>        balancer.updateStochasticCost(tableName.getNameAsString(), costFunctionName,<a name="line.520"></a>
-<span class="sourceLineNo">521</span>          "The percent of " + costFunctionName, costPercent);<a name="line.521"></a>
-<span class="sourceLineNo">522</span>      }<a name="line.522"></a>
-<span class="sourceLineNo">523</span>    }<a name="line.523"></a>
-<span class="sourceLineNo">524</span>  }<a name="line.524"></a>
-<span class="sourceLineNo">525</span><a name="line.525"></a>
-<span class="sourceLineNo">526</span>  private String functionCost() {<a name="line.526"></a>
-<span class="sourceLineNo">527</span>    StringBuilder builder = new StringBuilder();<a name="line.527"></a>
-<span class="sourceLineNo">528</span>    for (CostFunction c:costFunctions) {<a name="line.528"></a>
-<span class="sourceLineNo">529</span>      builder.append(c.getClass().getSimpleName());<a name="line.529"></a>
-<span class="sourceLineNo">530</span>      builder.append(" : (");<a name="line.530"></a>
-<span class="sourceLineNo">531</span>      builder.append(c.getMultiplier());<a name="line.531"></a>
-<span class="sourceLineNo">532</span>      builder.append(", ");<a name="line.532"></a>
-<span class="sourceLineNo">533</span>      builder.append(c.cost());<a name="line.533"></a>
-<span class="sourceLineNo">534</span>      builder.append("); ");<a name="line.534"></a>
-<span class="sourceLineNo">535</span>    }<a name="line.535"></a>
-<span class="sourceLineNo">536</span>    return builder.toString();<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>  /**<a name="line.539"></a>
-<span class="sourceLineNo">540</span>   * Create all of the RegionPlan's needed to move from the initial cluster state to the desired<a name="line.540"></a>
-<span class="sourceLineNo">541</span>   * state.<a name="line.541"></a>
-<span class="sourceLineNo">542</span>   *<a name="line.542"></a>
-<span class="sourceLineNo">543</span>   * @param cluster The state of the cluster<a name="line.543"></a>
-<span class="sourceLineNo">544</span>   * @return List of RegionPlan's that represent the moves needed to get to desired final state.<a name="line.544"></a>
-<span class="sourceLineNo">545</span>   */<a name="line.545"></a>
-<span class="sourceLineNo">546</span>  private List&lt;RegionPlan&gt; createRegionPlans(Cluster cluster) {<a name="line.546"></a>
-<span class="sourceLineNo">547</span>    List&lt;RegionPlan&gt; plans = new LinkedList&lt;&gt;();<a name="line.547"></a>
-<span class="sourceLineNo">548</span>    for (int regionIndex = 0;<a name="line.548"></a>
-<span class="sourceLineNo">549</span>         regionIndex &lt; cluster.regionIndexToServerIndex.length; regionIndex++) {<a name="line.549"></a>
-<span class="sourceLineNo">550</span>      int initialServerIndex = cluster.initialRegionIndexToServerIndex[regionIndex];<a name="line.550"></a>
-<span class="sourceLineNo">551</span>      int newServerIndex = cluster.regionIndexToServerIndex[regionIndex];<a name="line.551"></a>
-<span class="sourceLineNo">552</span><a name="line.552"></a>
-<span class="sourceLineNo">553</span>      if (initialServerIndex != newServerIndex) {<a name="line.553"></a>
-<span class="sourceLineNo">554</span>        RegionInfo region = cluster.regions[regionIndex];<a name="line.554"></a>
-<span class="sourceLineNo">555</span>        ServerName initialServer = cluster.servers[initialServerIndex];<a name="line.555"></a>
-<span class="sourceLineNo">556</span>        ServerName newServer = cluster.servers[newServerIndex];<a name="line.556"></a>
-<span class="sourceLineNo">557</span><a name="line.557"></a>
-<span class="sourceLineNo">558</span>        if (LOG.isTraceEnabled()) {<a name="line.558"></a>
-<span class="sourceLineNo">559</span>          LOG.trace("Moving Region " + region.getEncodedName() + " from server "<a name="line.559"></a>
-<span class="sourceLineNo">560</span>              + initialServer.getHostname() + " to " + newServer.getHostname());<a name="line.560"></a>
-<span class="sourceLineNo">561</span>        }<a name="line.561"></a>
-<span class="sourceLineNo">562</span>        RegionPlan rp = new RegionPlan(region, initialServer, newServer);<a name="line.562"></a>
-<span class="sourceLineNo">563</span>        plans.add(rp);<a name="line.563"></a>
-<span class="sourceLineNo">564</span>      }<a name="line.564"></a>
-<span class="sourceLineNo">565</span>    }<a name="line.565"></a>
-<span class="sourceLineNo">566</span>    return plans;<a name="line.566"></a>
-<span class="sourceLineNo">567</span>  }<a name="line.567"></a>
-<span class="sourceLineNo">568</span><a name="line.568"></a>
-<span class="sourceLineNo">569</span>  /**<a name="line.569"></a>
-<span class="sourceLineNo">570</span>   * Store the current region loads.<a name="line.570"></a>
-<span class="sourceLineNo">571</span>   */<a name="line.571"></a>
-<span class="sourceLineNo">572</span>  private synchronized void updateRegionLoad() {<a name="line.572"></a>
-<span class="sourceLineNo">573</span>    // We create a new hashmap so that regions that are no longer there are removed.<a name="line.573"></a>
-<span class="sourceLineNo">574</span>    // However we temporarily need the old loads so we can use them to keep the rolling average.<a name="line.574"></a>
-<span class="sourceLineNo">575</span>    Map&lt;String, Deque&lt;BalancerRegionLoad&gt;&gt; oldLoads = loads;<a name="line.575"></a>
-<span class="sourceLineNo">576</span>    loads = new HashMap&lt;&gt;();<a name="line.576"></a>
-<span class="sourceLineNo">577</span><a name="line.577"></a>
-<span class="sourceLineNo">578</span>    clusterStatus.getLiveServerMetrics().forEach((ServerName sn, ServerMetrics sm) -&gt; {<a name="line.578"></a>
-<span class="sourceLineNo">579</span>      sm.getRegionMetrics().forEach((byte[] regionName, RegionMetrics rm) -&gt; {<a name="line.579"></a>
-<span class="sourceLineNo">580</span>        String regionNameAsString = RegionInfo.getRegionNameAsString(regionName);<a name="line.580"></a>
-<span class="sourceLineNo">581</span>        Deque&lt;BalancerRegionLoad&gt; rLoads = oldLoads.get(regionNameAsString);<a name="line.581"></a>
-<span class="sourceLineNo">582</span>        if (rLoads == null) {<a name="line.582"></a>
-<span class="sourceLineNo">583</span>          rLoads = new ArrayDeque&lt;&gt;(numRegionLoadsToRemember + 1);<a name="line.583"></a>
-<span class="sourceLineNo">584</span>        } else if (rLoads.size() &gt;= numRegionLoadsToRemember) {<a name="line.584"></a>
-<span class="sourceLineNo">585</span>          rLoads.remove();<a name="line.585"></a>
-<span class="sourceLineNo">586</span>        }<a name="line.586"></a>
-<span class="sourceLineNo">587</span>        rLoads.add(new BalancerRegionLoad(rm));<a name="line.587"></a>
-<span class="sourceLineNo">588</span>        loads.put(regionNameAsString, rLoads);<a name="line.588"></a>
-<span class="sourceLineNo">589</span>      });<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>    for(CostFromRegionLoadFunction cost : regionLoadFunctions) {<a name="line.592"></a>
-<span class="sourceLineNo">593</span>      cost.setLoads(loads);<a name="line.593"></a>
-<span class="sourceLineNo">594</span>    }<a name="line.594"></a>
-<span class="sourceLineNo">595</span>  }<a name="line.595"></a>
-<span class="sourceLineNo">596</span><a name="line.596"></a>
-<span class="sourceLineNo">597</span>  protected void initCosts(Cluster cluster) {<a name="line.597"></a>
-<span class="sourceLineNo">598</span>    for (CostFunction c:costFunctions) {<a name="line.598"></a>
-<span class="sourceLineNo">599</span>      c.init(cluster);<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>  protected void updateCostsWithAction(Cluster cluster, Action action) {<a name="line.603"></a>
-<span class="sourceLineNo">604</span>    for (CostFunction c : costFunctions) {<a name="line.604"></a>
-<span class="sourceLineNo">605</span>      c.postAction(action);<a name="line.605"></a>
-<span class="sourceLineNo">606</span>    }<a name="line.606"></a>
-<span class="sourceLineNo">607</span>  }<a name="line.607"></a>
-<span class="sourceLineNo">608</span><a name="line.608"></a>
-<span class="sourceLineNo">609</span>  /**<a name="line.609"></a>
-<span class="sourceLineNo">610</span>   * Get the names of the cost functions<a name="line.610"></a>
-<span class="sourceLineNo">611</span>   */<a name="line.611"></a>
-<span class="sourceLineNo">612</span>  public String[] getCostFunctionNames() {<a name="line.612"></a>
-<span class="sourceLineNo">613</span>    if (costFunctions == null) return null;<a name="line.613"></a>
-<span class="sourceLineNo">614</span>    String[] ret = new String[costFunctions.size()];<a name="line.614"></a>
-<span class="sourceLineNo">615</span>    for (int i = 0; i &lt; costFunctions.size(); i++) {<a name="line.615"></a>
-<span class="sourceLineNo">616</span>      CostFunction c = costFunctions.get(i);<a name="line.616"></a>
-<span class="sourceLineNo">617</span>      ret[i] = c.getClass().getSimpleName();<a name="line.617"></a>
-<span class="sourceLineNo">618</span>    }<a name="line.618"></a>
-<span class="sourceLineNo">619</span><a name="line.619"></a>
-<span class="sourceLineNo">620</span>    return ret;<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>   * This is the main cost function.  It will compute a cost associated with a proposed cluster<a name="line.624"></a>
-<span class="sourceLineNo">625</span>   * state.  All different costs will be combined with their multipliers to produce a double cost.<a name="line.625"></a>
-<span class="sourceLineNo">626</span>   *<a name="line.626"></a>
-<span class="sourceLineNo">627</span>   * @param cluster The state of the cluster<a name="line.627"></a>
-<span class="sourceLineNo">628</span>   * @param previousCost the previous cost. This is used as an early out.<a name="line.628"></a>
-<span class="sourceLineNo">629</span>   * @return a double of a cost associated with the proposed cluster state.  This cost is an<a name="line.629"></a>
-<span class="sourceLineNo">630</span>   *         aggregate of all individual cost functions.<a name="line.630"></a>
-<span class="sourceLineNo">631</span>   */<a name="line.631"></a>
-<span class="sourceLineNo">632</span>  protected double computeCost(Cluster cluster, double previousCost) {<a name="line.632"></a>
-<span class="sourceLineNo">633</span>    double total = 0;<a name="line.633"></a>
-<span class="sourceLineNo">634</span><a name="line.634"></a>
-<span class="sourceLineNo">635</span>    for (int i = 0; i &lt; costFunctions.size(); i++) {<a name="line.635"></a>
-<span class="sourceLineNo">636</span>      CostFunction c = costFunctions.get(i);<a name="line.636"></a>
-<span class="sourceLineNo">637</span>      this.tempFunctionCosts[i] = 0.0;<a name="line.637"></a>
-<span class="sourceLineNo">638</span><a name="line.638"></a>
-<span class="sourceLineNo">639</span>      if (c.getMultiplier() &lt;= 0) {<a name="line.639"></a>
-<span class="sourceLineNo">640</span>        continue;<a name="line.640"></a>
-<span class="sourceLineNo">641</span>      }<a name="line.641"></a>
-<span class="sourceLineNo">642</span><a name="line.642"></a>
-<span class="sourceLineNo">643</span>      Float multiplier = c.getMultiplier();<a name="line.643"></a>
-<span class="sourceLineNo">644</span>      Double cost = c.cost();<a name="line.644"></a>
-<span class="sourceLineNo">645</span><a name="line.645"></a>
-<span class="sourceLineNo">646</span>      this.tempFunctionCosts[i] = multiplier*cost;<a name="line.646"></a>
-<span class="sourceLineNo">647</span>      total += this.tempFunctionCosts[i];<a name="line.647"></a>
-<span class="sourceLineNo">648</span><a name="line.648"></a>
-<span class="sourceLineNo">649</span>      if (total &gt; previousCost) {<a name="line.649"></a>
-<span class="sourceLineNo">650</span>        break;<a name="line.650"></a>
-<span class="sourceLineNo">651</span>      }<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>    return total;<a name="line.654"></a>
-<span class="sourceLineNo">655</span>  }<a name="line.655"></a>
-<span class="sourceLineNo">656</span><a name="line.656"></a>
-<span class="sourceLineNo">657</span>  /** Generates a candidate action to be applied to the cluster for cost function search */<a name="line.657"></a>
-<span class="sourceLineNo">658</span>  abstract static class CandidateGenerator {<a name="line.658"></a>
-<span class="sourceLineNo">659</span>    abstract Cluster.Action generate(Cluster cluster);<a name="line.659"></a>
-<span class="sourceLineNo">660</span><a name="line.660"></a>
-<span class="sourceLineNo">661</span>    /**<a name="line.661"></a>
-<span class="sourceLineNo">662</span>     * From a list of regions pick a random one. Null can be returned which<a name="line.662"></a>
-<span class="sourceLineNo">663</span>     * {@link StochasticLoadBalancer#balanceCluster(Map)} recognize as signal to try a region move<a name="line.663"></a>
-<span class="sourceLineNo">664</span>     * rather than swap.<a name="line.664"></a>
-<span class="sourceLineNo">665</span>     *<a name="line.665"></a>
-<span class="sourceLineNo">666</span>     * @param cluster        The state of the cluster<a name="line.666"></a>
-<span class="sourceLineNo">667</span>     * @param server         index of the server<a name="line.667"></a>
-<span class="sourceLineNo">668</span>     * @param chanceOfNoSwap Chance that this will decide to try a move rather<a name="line.668"></a>
-<span class="sourceLineNo">669</span>     *                       than a swap.<a name="line.669"></a>
-<span class="sourceLineNo">670</span>     * @return a random {@link RegionInfo} or null if an asymmetrical move is<a name="line.670"></a>
-<span class="sourceLineNo">671</span>     *         suggested.<a name="line.671"></a>
-<span class="sourceLineNo">672</span>     */<a name="line.672"></a>
-<span class="sourceLineNo">673</span>    protected int pickRandomRegion(Cluster cluster, int server, double chanceOfNoSwap) {<a name="line.673"></a>
-<span class="sourceLineNo">674</span>      // Check to see if this is just a move.<a name="line.674"></a>
-<span class="sourceLineNo">675</span>      if (cluster.regionsPerServer[server].length == 0 || RANDOM.nextFloat() &lt; chanceOfNoSwap) {<a name="line.675"></a>
-<span class="sourceLineNo">676</span>        // signal a move only.<a name="line.676"></a>
-<span class="sourceLineNo">677</span>        return -1;<a name="line.677"></a>
-<span class="sourceLineNo">678</span>      }<a name="line.678"></a>
-<span class="sourceLineNo">679</span>      int rand = RANDOM.nextInt(cluster.regionsPerServer[server].length);<a name="line.679"></a>
-<span class="sourceLineNo">680</span>      return cluster.regionsPerServer[server][rand];<a name="line.680"></a>
-<span class="sourceLineNo">681</span><a name="line.681"></a>
-<span class="sourceLineNo">682</span>    }<a name="line.682"></a>
-<span class="sourceLineNo">683</span>    protected int pickRandomServer(Cluster cluster) {<a name="line.683"></a>
-<span class="sourceLineNo">684</span>      if (cluster.numServers &lt; 1) {<a name="line.684"></a>
-<span class="sourceLineNo">685</span>        return -1;<a name="line.685"></a>
-<span class="sourceLineNo">686</span>      }<a name="line.686"></a>
-<span class="sourceLineNo">687</span><a name="line.687"></a>
-<span class="sourceLineNo">688</span>      return RANDOM.nextInt(cluster.numServers);<a name="line.688"></a>
-<span class="sourceLineNo">689</span>    }<a name="line.689"></a>
-<span class="sourceLineNo">690</span><a name="line.690"></a>
-<span class="sourceLineNo">691</span>    protected int pickRandomRack(Cluster cluster) {<a name="line.691"></a>
-<span class="sourceLineNo">692</span>      if (cluster.numRacks &lt; 1) {<a name="line.692"></a>
-<span class="sourceLineNo">693</span>        return -1;<a name="line.693"></a>
-<span class="sourceLineNo">694</span>      }<a name="line.694"></a>
-<span class="sourceLineNo">695</span><a name="line.695"></a>
-<span class="sourceLineNo">696</span>      return RANDOM.nextInt(cluster.numRacks);<a name="line.696"></a>
-<span class="sourceLineNo">697</span>    }<a name="line.697"></a>
-<span class="sourceLineNo">698</span><a name="line.698"></a>
-<span class="sourceLineNo">699</span>    protected int pickOtherRandomServer(Cluster cluster, int serverIndex) {<a name="line.699"></a>
-<span class="sourceLineNo">700</span>      if (cluster.numServers &lt; 2) {<a name="line.700"></a>
-<span class="sourceLineNo">701</span>        return -1;<a name="line.701"></a>
-<span class="sourceLineNo">702</span>      }<a name="line.702"></a>
-<span class="sourceLineNo">703</span>      while (true) {<a name="line.703"></a>
-<span class="sourceLineNo">704</span>        int otherServerIndex = pickRandomServer(cluster);<a name="line.704"></a>
-<span class="sourceLineNo">705</span>        if (otherServerIndex != serverIndex) {<a name="line.705"></a>
-<span class="sourceLineNo">706</span>          return otherServerIndex;<a name="line.706"></a>
-<span class="sourceLineNo">707</span>        }<a name="line.707"></a>
-<span class="sourceLineNo">708</span>      }<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>    protected int pickOtherRandomRack(Cluster cluster, int rackIndex) {<a name="line.711"></a>
-<span class="sourceLineNo">712</span>      if (cluster.numRacks &lt; 2) {<a name="line.712"></a>
-<span class="sourceLineNo">713</span>        return -1;<a name="line.713"></a>
-<span class="sourceLineNo">714</span>      }<a name="line.714"></a>
-<span class="sourceLineNo">715</span>      while (true) {<a name="line.715"></a>
-<span class="sourceLineNo">716</span>        int otherRackIndex = pickRandomRack(cluster);<a name="line.716"></a>
-<span class="sourceLineNo">717</span>        if (otherRackIndex != rackIndex) {<a name="line.717"></a>
-<span class="sourceLineNo">718</span>          return otherRackIndex;<a name="line.718"></a>
-<span class="sourceLineNo">719</span>        }<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>    protected Cluster.Action pickRandomRegions(Cluster cluster,<a name="line.723"></a>
-<span class="sourceLineNo">724</span>                                                       int thisServer,<a name="line.724"></a>
-<span class="sourceLineNo">725</span>                                                       int otherServer) {<a name="line.725"></a>
-<span class="sourceLineNo">726</span>      if (thisServer &lt; 0 || otherServer &lt; 0) {<a name="line.726"></a>
-<span class="sourceLineNo">727</span>        return Cluster.NullAction;<a name="line.727"></a>
-<span class="sourceLineNo">728</span>      }<a name="line.728"></a>
-<span class="sourceLineNo">729</span><a name="line.729"></a>
-<span class="sourceLineNo">730</span>      // Decide who is most likely to need another region<a name="line.730"></a>
-<span class="sourceLineNo">731</span>      int thisRegionCount = cluster.getNumRegions(thisServer);<a name="line.731"></a>
-<span class="sourceLineNo">732</span>      int otherRegionCount = cluster.getNumRegions(otherServer);<a name="line.732"></a>
-<span class="sourceLineNo">733</span><a name="line.733"></a>
-<span class="sourceLineNo">734</span>      // Assign the chance based upon the above<a name="line.734"></a>
-<span class="sourceLineNo">735</span>      double thisChance = (thisRegionCount &gt; otherRegionCount) ? 0 : 0.5;<a name="line.735"></a>
-<span class="sourceLineNo">736</span>      double otherChance = (thisRegionCount &lt;= otherRegionCount) ? 0 : 0.5;<a name="line.736"></a>
-<span class="sourceLineNo">737</span><a name="line.737"></a>
-<span class="sourceLineNo">738</span>      int thisRegion = pickRandomRegion(cluster, thisServer, thisChance);<a name="line.738"></a>
-<span class="sourceLineNo">739</span>      int otherRegion = pickRandomRegion(cluster, otherServer, otherChance);<a name="line.739"></a>
-<span class="sourceLineNo">740</span><a name="line.740"></a>
-<span class="sourceLineNo">741</span>      return getAction(thisServer, thisRegion, otherServer, otherRegion);<a name="line.741"></a>
-<span class="sourceLineNo">742</span>    }<a name="line.742"></a>
-<span class="sourceLineNo">743</span><a name="line.743"></a>
-<span class="sourceLineNo">744</span>    protected Cluster.Action getAction(int fromServer, int fromRegion,<a name="line.744"></a>
-<span class="sourceLineNo">745</span>        int toServer, int toRegion) {<a name="line.745"></a>
-<span class="sourceLineNo">746</span>      if (fromServer &lt; 0 || toServer &lt; 0) {<a name="line.746"></a>
-<span class="sourceLineNo">747</span>        return Cluster.NullAction;<a name="line.747"></a>
-<span class="sourceLineNo">748</span>      }<a name="line.748"></a>
-<span class="sourceLineNo">749</span>      if (fromRegion &gt; 0 &amp;&amp; toRegion &gt; 0) {<a name="line.749"></a>
-<span class="sourceLineNo">750</span>        return new Cluster.SwapRegionsAction(fromServer, fromRegion,<a name="line.750"></a>
-<span class="sourceLineNo">751</span>          toServer, toRegion);<a name="line.751"></a>
-<span class="sourceLineNo">752</span>      } else if (fromRegion &gt; 0) {<a name="line.752"></a>
-<span class="sourceLineNo">753</span>        return new Cluster.MoveRegionAction(fromRegion, fromServer, toServer);<a name="line.753"></a>
-<span class="sourceLineNo">754</span>      } else if (toRegion &gt; 0) {<a name="line.754"></a>
-<span class="sourceLineNo">755</span>        return new Cluster.MoveRegionAction(toRegion, toServer, fromServer);<a name="line.755"></a>
-<span class="sourceLineNo">756</span>      } else {<a name="line.756"></a>
-<span class="sourceLineNo">757</span>        return Cluster.NullAction;<a name="line.757"></a>
-<span class="sourceLineNo">758</span>      }<a name="line.758"></a>
-<span class="sourceLineNo">759</span>    }<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>     * Returns a random iteration order of indexes of an array with size length<a name="line.762"></a>
-<span class="sourceLineNo">763</span>     */<a name="line.763"></a>
-<span class="sourceLineNo">764</span>    protected List&lt;Integer&gt; getRandomIterationOrder(int length) {<a name="line.764"></a>
-<span class="sourceLineNo">765</span>      ArrayList&lt;Integer&gt; order = new ArrayList&lt;&gt;(length);<a name="line.765"></a>
-<span class="sourceLineNo">766</span>      for (int i = 0; i &lt; length; i++) {<a name="line.766"></a>
-<span class="sourceLineNo">767</span>        order.add(i);<a name="line.767"></a>
-<span class="sourceLineNo">768</span>      }<a name="line.768"></a>
-<span class="sourceLineNo">769</span>      Collections.shuffle(order);<a name="line.769"></a>
-<span class="sourceLineNo">770</span>      return order;<a name="line.770"></a>
-<span class="sourceLineNo">771</span>    }<a name="line.771"></a>
-<span class="sourceLineNo">772</span>  }<a name="line.772"></a>
-<span class="sourceLineNo">773</span><a name="line.773"></a>
-<span class="sourceLineNo">774</span>  static class RandomCandidateGenerator extends CandidateGenerator {<a name="line.774"></a>
+<span class="sourceLineNo">484</span>    metricsBalancer.balanceCluster(endTime - startTime);<a name="line.484"></a>
+<span class="sourceLineNo">485</span><a name="line.485"></a>
+<span class="sourceLineNo">486</span>    // update costs metrics<a name="line.486"></a>
+<span class="sourceLineNo">487</span>    updateStochasticCosts(tableName, curOverallCost, curFunctionCosts);<a name="line.487"></a>
+<span class="sourceLineNo">488</span>    if (initCost &gt; currentCost) {<a name="line.488"></a>
+<span class="sourceLineNo">489</span>      plans = createRegionPlans(cluster);<a name="line.489"></a>
+<span class="sourceLineNo">490</span>      LOG.info("Finished computing new load balance plan. Computation took {}" +<a name="line.490"></a>
+<span class="sourceLineNo">491</span>        " to try {} different iterations.  Found a solution that moves " +<a name="line.491"></a>
+<span class="sourceLineNo">492</span>        "{} regions; Going from a computed cost of {}" +<a name="line.492"></a>
+<span class="sourceLineNo">493</span>        " to a new cost of {}", java.time.Duration.ofMillis(endTime - startTime),<a name="line.493"></a>
+<span class="sourceLineNo">494</span>        step, plans.size(), initCost, currentCost);<a name="line.494"></a>
+<span class="sourceLineNo">495</span>      return plans;<a name="line.495"></a>
+<span class="sourceLineNo">496</span>    }<a name="line.496"></a>
+<span class="sourceLineNo">497</span>    LOG.info("Could not find a better load balance plan.  Tried {} different configurations in " +<a name="line.497"></a>
+<span class="sourceLineNo">498</span>      "{}, and did not find anything with a computed cost less than {}", step,<a name="line.498"></a>
+<span class="sourceLineNo">499</span>      java.time.Duration.ofMillis(endTime - startTime), initCost);<a name="line.499"></a>
+<span class="sourceLineNo">500</span>    return null;<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>  /**<a name="line.503"></a>
+<span class="sourceLineNo">504</span>   * update costs to JMX<a name="line.504"></a>
+<span class="sourceLineNo">505</span>   */<a name="line.505"></a>
+<span class="sourceLineNo">506</span>  private void updateStochasticCosts(TableName tableName, Double overall, Double[] subCosts) {<a name="line.506"></a>
+<span class="sourceLineNo">507</span>    if (tableName == null) return;<a name="line.507"></a>
+<span class="sourceLineNo">508</span><a name="line.508"></a>
+<span class="sourceLineNo">509</span>    // check if the metricsBalancer is MetricsStochasticBalancer before casting<a name="line.509"></a>
+<span class="sourceLineNo">510</span>    if (metricsBalancer instanceof MetricsStochasticBalancer) {<a name="line.510"></a>
+<span class="sourceLineNo">511</span>      MetricsStochasticBalancer balancer = (MetricsStochasticBalancer) metricsBalancer;<a name="line.511"></a>
+<span class="sourceLineNo">512</span>      // overall cost<a name="line.512"></a>
+<span class="sourceLineNo">513</span>      balancer.updateStochasticCost(tableName.getNameAsString(),<a name="line.513"></a>
+<span class="sourceLineNo">514</span>        "Overall", "Overall cost", overall);<a name="line.514"></a>
+<span class="sourceLineNo">515</span><a name="line.515"></a>
+<span class="sourceLineNo">516</span>      // each cost function<a name="line.516"></a>
+<span class="sourceLineNo">517</span>      for (int i = 0; i &lt; costFunctions.size(); i++) {<a name="line.517"></a>
+<span class="sourceLineNo">518</span>        CostFunction costFunction = costFunctions.get(i);<a name="line.518"></a>
+<span class="sourceLineNo">519</span>        String costFunctionName = costFunction.getClass().getSimpleName();<a name="line.519"></a>
+<span class="sourceLineNo">520</span>        Double costPercent = (overall == 0) ? 0 : (subCosts[i] / overall);<a name="line.520"></a>
+<span class="sourceLineNo">521</span>        // TODO: cost function may need a specific description<a name="line.521"></a>
+<span class="sourceLineNo">522</span>        balancer.updateStochasticCost(tableName.getNameAsString(), costFunctionName,<a name="line.522"></a>
+<span class="sourceLineNo">523</span>          "The percent of " + costFunctionName, costPercent);<a name="line.523"></a>
+<span class="sourceLineNo">524</span>      }<a name="line.524"></a>
+<span class="sourceLineNo">525</span>    }<a name="line.525"></a>
+<span class="sourceLineNo">526</span>  }<a name="line.526"></a>
+<span class="sourceLineNo">527</span><a name="line.527"></a>
+<span class="sourceLineNo">528</span>  private String functionCost() {<a name="line.528"></a>
+<span class="sourceLineNo">529</span>    StringBuilder builder = new StringBuilder();<a name="line.529"></a>
+<span class="sourceLineNo">530</span>    for (CostFunction c:costFunctions) {<a name="line.530"></a>
+<span class="sourceLineNo">531</span>      builder.append(c.getClass().getSimpleName());<a name="line.531"></a>
+<span class="sourceLineNo">532</span>      builder.append(" : (");<a name="line.532"></a>
+<span class="sourceLineNo">533</span>      builder.append(c.getMultiplier());<a name="line.533"></a>
+<span class="sourceLineNo">534</span>      builder.append(", ");<a name="line.534"></a>
+<span class="sourceLineNo">535</span>      builder.append(c.cost());<a name="line.535"></a>
+<span class="sourceLineNo">536</span>      builder.append("); ");<a name="line.536"></a>
+<span class="sourceLineNo">537</span>    }<a name="line.537"></a>
+<span class="sourceLineNo">538</span>    return builder.toString();<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>  /**<a name="line.541"></a>
+<span class="sourceLineNo">542</span>   * Create all of the RegionPlan's needed to move from the initial cluster state to the desired<a name="line.542"></a>
+<span class="sourceLineNo">543</span>   * state.<a name="line.543"></a>
+<span class="sourceLineNo">544</span>   *<a name="line.544"></a>
+<span class="sourceLineNo">545</span>   * @param cluster The state of the cluster<a name="line.545"></a>
+<span class="sourceLineNo">546</span>   * @return List of RegionPlan's that represent the moves needed to get to desired final state.<a name="line.546"></a>
+<span class="sourceLineNo">547</span>   */<a name="line.547"></a>
+<span class="sourceLineNo">548</span>  private List&lt;RegionPlan&gt; createRegionPlans(Cluster cluster) {<a name="line.548"></a>
+<span class="sourceLineNo">549</span>    List&lt;RegionPlan&gt; plans = new LinkedList&lt;&gt;();<a name="line.549"></a>
+<span class="sourceLineNo">550</span>    for (int regionIndex = 0;<a name="line.550"></a>
+<span class="sourceLineNo">551</span>         regionIndex &lt; cluster.regionIndexToServerIndex.length; regionIndex++) {<a name="line.551"></a>
+<span class="sourceLineNo">552</span>      int initialServerIndex = cluster.initialRegionIndexToServerIndex[regionIndex];<a name="line.552"></a>
+<span class="sourceLineNo">553</span>      int newServerIndex = cluster.regionIndexToServerIndex[regionIndex];<a name="line.553"></a>
+<span class="sourceLineNo">554</span><a name="line.554"></a>
+<span class="sourceLineNo">555</span>      if (initialServerIndex != newServerIndex) {<a name="line.555"></a>
+<span class="sourceLineNo">556</span>        RegionInfo region = cluster.regions[regionIndex];<a name="line.556"></a>
+<span class="sourceLineNo">557</span>        ServerName initialServer = cluster.servers[initialServerIndex];<a name="line.557"></a>
+<span class="sourceLineNo">558</span>        ServerName newServer = cluster.servers[newServerIndex];<a name="line.558"></a>
+<span class="sourceLineNo">559</span><a name="line.559"></a>
+<span class="sourceLineNo">560</span>        if (LOG.isTraceEnabled()) {<a name="line.560"></a>
+<span class="sourceLineNo">561</span>          LOG.trace("Moving Region " + region.getEncodedName() + " from server "<a name="line.561"></a>
+<span class="sourceLineNo">562</span>              + initialServer.getHostname() + " to " + newServer.getHostname());<a name="line.562"></a>
+<span class="sourceLineNo">563</span>        }<a name="line.563"></a>
+<span class="sourceLineNo">564</span>        RegionPlan rp = new RegionPlan(region, initialServer, newServer);<a name="line.564"></a>
+<span class="sourceLineNo">565</span>        plans.add(rp);<a name="line.565"></a>
+<span class="sourceLineNo">566</span>      }<a name="line.566"></a>
+<span class="sourceLineNo">567</span>    }<a name="line.567"></a>
+<span class="sourceLineNo">568</span>    return plans;<a name="line.568"></a>
+<span class="sourceLineNo">569</span>  }<a name="line.569"></a>
+<span class="sourceLineNo">570</span><a name="line.570"></a>
+<span class="sourceLineNo">571</span>  /**<a name="line.571"></a>
+<span class="sourceLineNo">572</span>   * Store the current region loads.<a name="line.572"></a>
+<span class="sourceLineNo">573</span>   */<a name="line.573"></a>
+<span class="sourceLineNo">574</span>  private synchronized void updateRegionLoad() {<a name="line.574"></a>
+<span class="sourceLineNo">575</span>    // We create a new hashmap so that regions that are no longer there are removed.<a name="line.575"></a>
+<span class="sourceLineNo">576</span>    // However we temporarily need the old loads so we can use them to keep the rolling average.<a name="line.576"></a>
+<span class="sourceLineNo">577</span>    Map&lt;String, Deque&lt;BalancerRegionLoad&gt;&gt; oldLoads = loads;<a name="line.577"></a>
+<span class="sourceLineNo">578</span>    loads = new HashMap&lt;&gt;();<a name="line.578"></a>
+<span class="sourceLineNo">579</span><a name="line.579"></a>
+<span class="sourceLineNo">580</span>    clusterStatus.getLiveServerMetrics().forEach((ServerName sn, ServerMetrics sm) -&gt; {<a name="line.580"></a>
+<span class="sourceLineNo">581</span>      sm.getRegionMetrics().forEach((byte[] regionName, RegionMetrics rm) -&gt; {<a name="line.581"></a>
+<span class="sourceLineNo">582</span>        String regionNameAsString = RegionInfo.getRegionNameAsString(regionName);<a name="line.582"></a>
+<span class="sourceLineNo">583</span>        Deque&lt;BalancerRegionLoad&gt; rLoads = oldLoads.get(regionNameAsString);<a name="line.583"></a>
+<span class="sourceLineNo">584</span>        if (rLoads == null) {<a name="line.584"></a>
+<span class="sourceLineNo">585</span>          rLoads = new ArrayDeque&lt;&gt;(numRegionLoadsToRemember + 1);<a name="line.585"></a>
+<span class="sourceLineNo">586</span>        } else if (rLoads.size() &gt;= numRegionLoadsToRemember) {<a name="line.586"></a>
+<span class="sourceLineNo">587</span>          rLoads.remove();<a name="line.587"></a>
+<span class="sourceLineNo">588</span>        }<a name="line.588"></a>
+<span class="sourceLineNo">589</span>        rLoads.add(new BalancerRegionLoad(rm));<a name="line.589"></a>
+<span class="sourceLineNo">590</span>        loads.put(regionNameAsString, rLoads);<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>    for(CostFromRegionLoadFunction cost : regionLoadFunctions) {<a name="line.594"></a>
+<span class="sourceLineNo">595</span>      cost.setLoads(loads);<a name="line.595"></a>
+<span class="sourceLineNo">596</span>    }<a name="line.596"></a>
+<span class="sourceLineNo">597</span>  }<a name="line.597"></a>
+<span class="sourceLineNo">598</span><a name="line.598"></a>
+<span class="sourceLineNo">599</span>  protected void initCosts(Cluster cluster) {<a name="line.599"></a>
+<span class="sourceLineNo">600</span>    for (CostFunction c:costFunctions) {<a name="line.600"></a>
+<span class="sourceLineNo">601</span>      c.init(cluster);<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><a name="line.604"></a>
+<span class="sourceLineNo">605</span>  protected void updateCostsWithAction(Cluster cluster, Action action) {<a name="line.605"></a>
+<span class="sourceLineNo">606</span>    for (CostFunction c : costFunctions) {<a name="line.606"></a>
+<span class="sourceLineNo">607</span>      c.postAction(action);<a name="line.607"></a>
+<span class="sourceLineNo">608</span>    }<a name="line.608"></a>
+<span class="sourceLineNo">609</span>  }<a name="line.609"></a>
+<span class="sourceLineNo">610</span><a name="line.610"></a>
+<span class="sourceLineNo">611</span>  /**<a name="line.611"></a>
+<span class="sourceLineNo">612</span>   * Get the names of the cost functions<a name="line.612"></a>
+<span class="sourceLineNo">613</span>   */<a name="line.613"></a>
+<span class="sourceLineNo">614</span>  public String[] getCostFunctionNames() {<a name="line.614"></a>
+<span class="sourceLineNo">615</span>    if (costFunctions == null) return null;<a name="line.615"></a>
+<span class="sourceLineNo">616</span>    String[] ret = new String[costFunctions.size()];<a name="line.616"></a>
+<span class="sourceLineNo">617</span>    for (int i = 0; i &lt; costFunctions.size(); i++) {<a name="line.617"></a>
+<span class="sourceLineNo">618</span>      CostFunction c = costFunctions.get(i);<a name="line.618"></a>
+<span class="sourceLineNo">619</span>      ret[i] = c.getClass().getSimpleName();<a name="line.619"></a>
+<span class="sourceLineNo">620</span>    }<a name="line.620"></a>
+<span class="sourceLineNo">621</span><a name="line.621"></a>
+<span class="sourceLineNo">622</span>    return ret;<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>  /**<a name="line.625"></a>
+<span class="sourceLineNo">626</span>   * This is the main cost function.  It will compute a cost associated with a proposed cluster<a name="line.626"></a>
+<span class="sourceLineNo">627</span>   * state.  All different costs will be combined with their multipliers to produce a double cost.<a name="line.627"></a>
+<span class="sourceLineNo">628</span>   *<a name="line.628"></a>
+<span class="sourceLineNo">629</span>   * @param cluster The state of the cluster<a name="line.629"></a>
+<span class="sourceLineNo">630</span>   * @param previousCost the previous cost. This is used as an early out.<a name="line.630"></a>
+<span class="sourceLineNo">631</span>   * @return a double of a cost associated with the proposed cluster state.  This cost is an<a name="line.631"></a>
+<span class="sourceLineNo">632</span>   *         aggregate of all individual cost functions.<a name="line.632"></a>
+<span class="sourceLineNo">633</span>   */<a name="line.633"></a>
+<span class="sourceLineNo">634</span>  protected double computeCost(Cluster cluster, double previousCost) {<a name="line.634"></a>
+<span class="sourceLineNo">635</span>    double total = 0;<a name="line.635"></a>
+<span class="sourceLineNo">636</span><a name="line.636"></a>
+<span class="sourceLineNo">637</span>    for (int i = 0; i &lt; costFunctions.size(); i++) {<a name="line.637"></a>
+<span class="sourceLineNo">638</span>      CostFunction c = costFunctions.get(i);<a name="line.638"></a>
+<span class="sourceLineNo">639</span>      this.tempFunctionCosts[i] = 0.0;<a name="line.639"></a>
+<span class="sourceLineNo">640</span><a name="line.640"></a>
+<span class="sourceLineNo">641</span>      if (c.getMultiplier() &lt;= 0) {<a name="line.641"></a>
+<span class="sourceLineNo">642</span>        continue;<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>      Float multiplier = c.getMultiplier();<a name="line.645"></a>
+<span class="sourceLineNo">646</span>      Double cost = c.cost();<a name="line.646"></a>
+<span class="sourceLineNo">647</span><a name="line.647"></a>
+<span class="sourceLineNo">648</span>      this.tempFunctionCosts[i] = multiplier*cost;<a name="line.648"></a>
+<span class="sourceLineNo">649</span>      total += this.tempFunctionCosts[i];<a name="line.649"></a>
+<span class="sourceLineNo">650</span><a name="line.650"></a>
+<span class="sourceLineNo">651</span>      if (total &gt; previousCost) {<a name="line.651"></a>
+<span class="sourceLineNo">652</span>        break;<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><a name="line.655"></a>
+<span class="sourceLineNo">656</span>    return total;<a name="line.656"></a>
+<span class="sourceLineNo">657</span>  }<a name="line.657"></a>
+<span class="sourceLineNo">658</span><a name="line.658"></a>
+<span class="sourceLineNo">659</span>  /** Generates a candidate action to be applied to the cluster for cost function search */<a name="line.659"></a>
+<span class="sourceLineNo">660</span>  abstract static class CandidateGenerator {<a name="line.660"></a>
+<span class="sourceLineNo">661</span>    abstract Cluster.Action generate(Cluster cluster);<a name="line.661"></a>
+<span class="sourceLineNo">662</span><a name="line.662"></a>
+<span class="sourceLineNo">663</span>    /**<a name="line.663"></a>
+<span class="sourceLineNo">664</span>     * From a list of regions pick a random one. Null can be returned which<a name="line.664"></a>
+<span class="sourceLineNo">665</span>     * {@link StochasticLoadBalancer#balanceCluster(Map)} recognize as signal to try a region move<a name="line.665"></a>
+<span class="sourceLineNo">666</span>     * rather than swap.<a name="line.666"></a>
+<span class="sourceLineNo">667</span>     *<a name="line.667"></a>
+<span class="sourceLineNo">668</span>     * @param cluster        The state of the cluster<a name="line.668"></a>
+<span class="sourceLineNo">669</span>     * @param server         index of the server<a name="line.669"></a>
+<span class="sourceLineNo">670</span>     * @param chanceOfNoSwap Chance that this will decide to try a move rather<a name="line.670"></a>
+<span class="sourceLineNo">671</span>     *                       than a swap.<a name="line.671"></a>
+<span class="sourceLineNo">672</span>     * @return a random {@link RegionInfo} or null if an asymmetrical move is<a name="line.672"></a>
+<span class="sourceLineNo">673</span>     *         suggested.<a name="line.673"></a>
+<span class="sourceLineNo">674</span>     */<a name="line.674"></a>
+<span class="sourceLineNo">675</span>    protected int pickRandomRegion(Cluster cluster, int server, double chanceOfNoSwap) {<a name="line.675"></a>
+<span class="sourceLineNo">676</span>      // Check to see if this is just a move.<a name="line.676"></a>
+<span class="sourceLineNo">677</span>      if (cluster.regionsPerServer[server].length == 0 || RANDOM.nextFloat() &lt; chanceOfNoSwap) {<a name="line.677"></a>
+<span class="sourceLineNo">678</span>        // signal a move only.<a name="line.678"></a>
+<span class="sourceLineNo">679</span>        return -1;<a name="line.679"></a>
+<span class="sourceLineNo">680</span>      }<a name="line.680"></a>
+<span class="sourceLineNo">681</span>      int rand = RANDOM.nextInt(cluster.regionsPerServer[server].length);<a name="line.681"></a>
+<span class="sourceLineNo">682</span>      return cluster.regionsPerServer[server][rand];<a name="line.682"></a>
+<span class="sourceLineNo">683</span><a name="line.683"></a>
+<span class="sourceLineNo">684</span>    }<a name="line.684"></a>
+<span class="sourceLineNo">685</span>    protected int pickRandomServer(Cluster cluster) {<a name="line.685"></a>
+<span class="sourceLineNo">686</span>      if (cluster.numServers &lt; 1) {<a name="line.686"></a>
+<span class="sourceLineNo">687</span>        return -1;<a name="line.687"></a>
+<span class="sourceLineNo">688</span>      }<a name="line.688"></a>
+<span class="sourceLineNo">689</span><a name="line.689"></a>
+<span class="sourceLineNo">690</span>      return RANDOM.nextInt(cluster.numServers);<a name="line.690"></a>
+<span class="sourceLineNo">691</span>    }<a name="line.691"></a>
+<span class="sourceLineNo">692</span><a name="line.692"></a>
+<span class="sourceLineNo">693</span>    protected int pickRandomRack(Cluster cluster) {<a name="line.693"></a>
+<span class="sourceLineNo">694</span>      if (cluster.numRacks &lt; 1) {<a name="line.694"></a>
+<span class="sourceLineNo">695</span>        return -1;<a name="line.695"></a>
+<span class="sourceLineNo">696</span>      }<a name="line.696"></a>
+<span class="sourceLineNo">697</span><a name="line.697"></a>
+<span class="sourceLineNo">698</span>      return RANDOM.nextInt(cluster.numRacks);<a name="line.698"></a>
+<span class="sourceLineNo">699</span>    }<a name="line.699"></a>
+<span class="sourceLineNo">700</span><a name="line.700"></a>
+<span class="sourceLineNo">701</span>    protected int pickOtherRandomServer(Cluster cluster, int serverIndex) {<a name="line.701"></a>
+<span class="sourceLineNo">702</span>      if (cluster.numServers &lt; 2) {<a name="line.702"></a>
+<span class="sourceLineNo">703</span>        return -1;<a name="line.703"></a>
+<span class="sourceLineNo">704</span>      }<a name="line.704"></a>
+<span class="sourceLineNo">705</span>      while (true) {<a name="line.705"></a>
+<span class="sourceLineNo">706</span>        int otherServerIndex = pickRandomServer(cluster);<a name="line.706"></a>
+<span class="sourceLineNo">707</span>        if (otherServerIndex != serverIndex) {<a name="line.707"></a>
+<span class="sourceLineNo">708</span>          return otherServerIndex;<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><a name="line.712"></a>
+<span class="sourceLineNo">713</span>    protected int pickOtherRandomRack(Cluster cluster, int rackIndex) {<a name="line.713"></a>
+<span class="sourceLineNo">714</span>      if (cluster.numRacks &lt; 2) {<a name="line.714"></a>
+<span class="sourceLineNo">715</span>        return -1;<a name="line.715"></a>
+<span class="sourceLineNo">716</span>      }<a name="line.716"></a>
+<span class="sourceLineNo">717</span>      while (true) {<a name="line.717"></a>
+<span class="sourceLineNo">718</span>        int otherRackIndex = pickRandomRack(cluster);<a name="line.718"></a>
+<span class="sourceLineNo">719</span>        if (otherRackIndex != rackIndex) {<a name="line.719"></a>
+<span class="sourceLineNo">720</span>          return otherRackIndex;<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><a name="line.724"></a>
+<span class="sourceLineNo">725</span>    protected Cluster.Action pickRandomRegions(Cluster cluster,<a name="line.725"></a>
+<span class="sourceLineNo">726</span>                                                       int thisServer,<a name="line.726"></a>
+<span class="sourceLineNo">727</span>                                                       int otherServer) {<a name="line.727"></a>
+<span class="sourceLineNo">728</span>      if (thisServer &lt; 0 || otherServer &lt; 0) {<a name="line.728"></a>
+<span class="sourceLineNo">729</span>        return Cluster.NullAction;<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>      // Decide who is most likely to need another region<a name="line.732"></a>
+<span class="sourceLineNo">733</span>      int thisRegionCount = cluster.getNumRegions(thisServer);<a name="line.733"></a>
+<span class="sourceLineNo">734</span>      int otherRegionCount = cluster.getNumRegions(otherServer);<a name="line.734"></a>
+<span class="sourceLineNo">735</span><a name="line.735"></a>
+<span class="sourceLineNo">736</span>      // Assign the chance based upon the above<a name="line.736"></a>
+<span class="sourceLineNo">737</span>      double thisChance = (thisRegionCount &gt; otherRegionCount) ? 0 : 0.5;<a name="line.737"></a>
+<span class="sourceLineNo">738</span>      double otherChance = (thisRegionCount &lt;= otherRegionCount) ? 0 : 0.5;<a name="line.738"></a>
+<span class="sourceLineNo">739</span><a name="line.739"></a>
+<span class="sourceLineNo">740</span>      int thisRegion = pickRandomRegion(cluster, thisServer, thisChance);<a name="line.740"></a>
+<span class="sourceLineNo">741</span>      int otherRegion = pickRandomRegion(cluster, otherServer, otherChance);<a name="line.741"></a>
+<span class="sourceLineNo">742</span><a name="line.742"></a>
+<span class="sourceLineNo">743</span>      return getAction(thisServer, thisRegion, otherServer, otherRegion);<a name="line.743"></a>
+<span class="sourceLineNo">744</span>    }<a name="line.744"></a>
+<span class="sourceLineNo">745</span><a name="line.745"></a>
+<span class="sourceLineNo">746</span>    protected Cluster.Action getAction(int fromServer, int fromRegion,<a name="line.746"></a>
+<span class="sourceLineNo">747</span>        int toServer, int toRegion) {<a name="line.747"></a>
+<span class="sourceLineNo">748</span>      if (fromServer &lt; 0 || toServer &lt; 0) {<a name="line.748"></a>
+<span class="sourceLineNo">749</span>        return Cluster.NullAction;<a name="line.749"></a>
+<span class="sourceLineNo">750</span>      }<a name="line.750"></a>
+<span class="sourceLineNo">751</span>      if (fromRegion &gt; 0 &amp;&amp; toRegion &gt; 0) {<a name="line.751"></a>
+<span class="sourceLineNo">752</span>        return new Cluster.SwapRegionsAction(fromServer, fromRegion,<a name="line.752"></a>
+<span class="sourceLineNo">753</span>          toServer, toRegion);<a name="line.753"></a>
+<span class="sourceLineNo">754</span>      } else if (fromRegion &gt; 0) {<a name="line.754"></a>
+<span class="sourceLineNo">755</span>        return new Cluster.MoveRegionAction(fromRegion, fromServer, toServer);<a name="line.755"></a>
+<span class="sourceLineNo">756</span>      } else if (toRegion &gt; 0) {<a name="line.756"></a>
+<span class="sourceLineNo">757</span>        return new Cluster.MoveRegionAction(toRegion, toServer, fromServer);<a name="line.757"></a>
+<span class="sourceLineNo">758</span>      } else {<a name="line.758"></a>
+<span class="sourceLineNo">759</span>        return Cluster.NullAction;<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><a name="line.762"></a>
+<span class="sourceLineNo">763</span>    /**<a name="line.763"></a>
+<span class="sourceLineNo">764</span>     * Returns a random iteration order of indexes of an array with size length<a name="line.764"></a>
+<span class="sourceLineNo">765</span>     */<a name="line.765"></a>
+<span class="sourceLineNo">766</span>    protected List&lt;Integer&gt; getRandomIterationOrder(int length) {<a name="line.766"></a>
+<span class="sourceLineNo">767</span>      ArrayList&lt;Integer&gt; order = new ArrayList&lt;&gt;(length);<a name="line.767"></a>
+<span class="sourceLineNo">768</span>      for (int i = 0; i &lt; length; i++) {<a name="line.768"></a>
+<span class="sourceLineNo">769</span>        order.add(i);<a name="line.769"></a>
+<span class="sourceLineNo">770</span>      }<a name="line.770"></a>
+<span class="sourceLineNo">771</span>      Collections.shuffle(order);<a name="line.771"></a>
+<span class="sourceLineNo">772</span>      return order;<a name="line.772"></a>
+<span class="sourceLineNo">773</span>    }<a name="line.773"></a>
+<span class="sourceLineNo">774</span>  }<a name="line.774"></a>
 <span class="sourceLineNo">775</span><a name="line.775"></a>
-<span class="sourceLineNo">776</span>    @Override<a name="line.776"></a>
-<span class="sourceLineNo">777</span>    Cluster.Action generate(Cluster cluster) {<a name="line.777"></a>
-<span class="sourceLineNo">778</span><a name="line.778"></a>
-<span class="sourceLineNo">779</span>      int thisServer = pickRandomServer(cluster);<a name="line.779"></a>
+<span class="sourceLineNo">776</span>  static class RandomCandidateGenerator extends CandidateGenerator {<a name="line.776"></a>
+<span class="sourceLineNo">777</span><a name="line.777"></a>
+<span class="sourceLineNo">778</span>    @Override<a name="line.778"></a>
+<span class="sourceLineNo">779</span>    Cluster.Action generate(Cluster cluster) {<a name="line.779"></a>
 <span class="sourceLineNo">780</span><a name="line.780"></a>
-<span class="sourceLineNo">781</span>      // Pick the other server<a name="line.781"></a>
-<span class="sourceLineNo">782</span>      int otherServer = pickOtherRandomServer(cluster, thisServer);<a name="line.782"></a>
-<span class="sourceLineNo">783</span><a name="line.783"></a>
-<span class="sourceLineNo">784</span>      return pickRandomRegions(cluster, thisServer, otherServer);<a name="line.784"></a>
-<span class="sourceLineNo">785</span>    }<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>  static class LoadCandidateGenerator extends CandidateGenerator {<a name="line.788"></a>
+<span class="sourceLineNo">781</span>      int thisServer = pickRandomServer(cluster);<a name="line.781"></a>
+<span class="sourceLineNo">782</span><a name="line.782"></a>
+<span class="sourceLineNo">783</span>      // Pick the other server<a name="line.783"></a>
+<span class="sourceLineNo">784</span>      int otherServer = pickOtherRandomServer(cluster, thisServer);<a name="line.784"></a>
+<span class="sourceLineNo">785</span><a name="line.785"></a>
+<span class="sourceLineNo">786</span>      return pickRandomRegions(cluster, thisServer, otherServer);<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><a name="line.789"></a>
-<span class="sourceLineNo">790</span>    @Override<a name="line.790"></a>
-<span class="sourceLineNo">791</span>    Cluster.Action generate(Cluster cluster) {<a name="line.791"></a>
-<span class="sourceLineNo">792</span>      cluster.sortServersByRegionCount();<a name="line.792"></a>
-<span class="sourceLineNo">793</span>      int thisServer = pickMostLoadedServer(cluster, -1);<a name="line.793"></a>
-<span class="sourceLineNo">794</span>      int otherServer = pickLeastLoadedServer(cluster, thisServer);<a name="line.794"></a>
-<span class="sourceLineNo">795</span><a name="line.795"></a>
-<span class="sourceLineNo">796</span>      return pickRandomRegions(cluster, thisServer, otherServer);<a name="line.796"></a>
-<span class="sourceLineNo">797</span>    }<a name="line.797"></a>
-<span class="sourceLineNo">798</span><a name="line.798"></a>
-<span class="sourceLineNo">799</span>    private int pickLeastLoadedServer(final Cluster cluster, int thisServer) {<a name="line.799"></a>
-<span class="sourceLineNo">800</span>      Integer[] servers = cluster.serverIndicesSortedByRegionCount;<a name="line.800"></a>
-<span class="sourceLineNo">801</span><a name="line.801"></a>
-<span class="sourceLineNo">802</span>      int index = 0;<a name="line.802"></a>
-<span class="sourceLineNo">803</span>      while (servers[index] == null || servers[index] == thisServer) {<a name="line.803"></a>
-<span class="sourceLineNo">804</span>        index++;<a name="line.804"></a>
-<span class="sourceLineNo">805</span>        if (index == servers.length) {<a name="line.805"></a>
-<span class="sourceLineNo">806</span>          return -1;<a name="line.806"></a>
-<span class="sourceLineNo">807</span>        }<a name="line.807"></a>
-<span class="sourceLineNo">808</span>      }<a name="line.808"></a>
-<span class="sourceLineNo">809</span>      return servers[index];<a name="line.809"></a>
-<span class="sourceLineNo">810</span>    }<a name="line.810"></a>
-<span class="sourceLineNo">811</span><a name="line.811"></a>
-<span class="sourceLineNo">812</span>    private int pickMostLoadedServer(final Cluster cluster, int thisServer) {<a name="line.812"></a>
-<span class="sourceLineNo">813</span>      Integer[] servers = cluster.serverIndicesSortedByRegionCount;<a name="line.813"></a>
-<span class="sourceLineNo">814</span><a name="line.814"></a>
-<span class="sourceLineNo">815</span>      int index = servers.length - 1;<a name="line.815"></a>
-<span class="sourceLineNo">816</span>      while (servers[index] == null || servers[index] == thisServer) {<a name="line.816"></a>
-<span class="sourceLineNo">817</span>        index--;<a name="line.817"></a>
-<span class="sourceLineNo">818</span>        if (index &lt; 0) {<a name="line.818"></a>
-<span class="sourceLineNo">819</span>          return -1;<a name="line.819"></a>
-<span class="sourceLineNo">820</span>        }<a name="line.820"></a>
-<span class="sourceLineNo">821</span>      }<a name="line.821"></a>
-<span class="sourceLineNo">822</span>      return servers[index];<a name="line.822"></a>
-<span class="sourceLineNo">823</span>    }<a name="line.823"></a>
-<span class="sourceLineNo">824</span>  }<a name="line.824"></a>
-<span class="sourceLineNo">825</span><a name="line.825"></a>
-<span class="sourceLineNo">826</span>  static class LocalityBasedCandidateGenerator extends CandidateGenerator {<a name="line.826"></a>
+<span class="sourceLineNo">790</span>  static class LoadCandidateGenerator extends CandidateGenerator {<a name="line.790"></a>
+<span class="sourceLineNo">791</span><a name="line.791"></a>
+<span class="sourceLineNo">792</span>    @Override<a name="line.792"></a>
+<span class="sourceLineNo">793</span>    Cluster.Action generate(Cluster cluster) {<a name="line.793"></a>
+<span class="sourceLineNo">794</span>      cluster.sortServersByRegionCount();<a name="line.794"></a>
+<span class="sourceLineNo">795</span>      int thisServer = pickMostLoadedServer(cluster, -1);<a name="line.795"></a>
+<span class="sourceLineNo">796</span>      int otherServer = pickLeastLoadedServer(cluster, thisServer);<a name="line.796"></a>
+<span class="sourceLineNo">797</span><a name="line.797"></a>
+<span class="sourceLineNo">798</span>      return pickRandomRegions(cluster, thisServer, otherServer);<a name="line.798"></a>
+<span class="sourceLineNo">799</span>    }<a name="line.799"></a>
+<span class="sourceLineNo">800</span><a name="line.800"></a>
+<span class="sourceLineNo">801</span>    private int pickLeastLoadedServer(final Cluster cluster, int thisServer) {<a name="line.801"></a>
+<span class="sourceLineNo">802</span>      Integer[] servers = cluster.serverIndicesSortedByRegionCount;<a name="line.802"></a>
+<span class="sourceLineNo">803</span><a name="line.803"></a>
+<span class="sourceLineNo">804</span>      int index = 0;<a name="line.804"></a>
+<span class="sourceLineNo">805</span>      while (servers[index] == null || servers[index] == thisServer) {<a name="line.805"></a>
+<span class="sourceLineNo">806</span>        index++;<a name="line.806"></a>
+<span class="sourceLineNo">807</span>        if (index == servers.length) {<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>      }<a name="line.810"></a>
+<span class="sourceLineNo">811</span>      return servers[index];<a name="line.811"></a>
+<span class="sourceLineNo">812</span>    }<a name="line.812"></a>
+<span class="sourceLineNo">813</span><a name="line.813"></a>
+<span class="sourceLineNo">814</span>    private int pickMostLoadedServer(final Cluster cluster, int thisServer) {<a name="line.814"></a>
+<span class="sourceLineNo">815</span>      Integer[] servers = cluster.serverIndicesSortedByRegionCount;<a name="line.815"></a>
+<span class="sourceLineNo">816</span><a name="line.816"></a>
+<span class="sourceLineNo">817</span>      int index = servers.length - 1;<a name="line.817"></a>
+<span class="sourceLineNo">818</span>      while (servers[index] == null || servers[index] == thisServer) {<a name="line.818"></a>
+<span class="sourceLineNo">819</span>        index--;<a name="line.819"></a>
+<span class="sourceLineNo">820</span>        if (index &lt; 0) {<a name="line.820"></a>
+<span class="sourceLineNo">821</span>          return -1;<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>      return servers[index];<a name="line.824"></a>
+<span class="sourceLineNo">825</span>    }<a name="line.825"></a>
+<span class="sourceLineNo">826</span>  }<a name="line.826"></a>
 <span class="sourceLineNo">827</span><a name="line.827"></a>
-<span class="sourceLineNo">828</span>    private MasterServices masterServices;<a name="line.828"></a>
+<span class="sourceLineNo">828</span>  static class LocalityBasedCandidateGenerator extends CandidateGenerator {<a name="line.828"></a>
 <span class="sourceLineNo">829</span><a name="line.829"></a>
-<span class="sourceLineNo">830</span>    LocalityBasedCandidateGenerator(MasterServices masterServices) {<a name="line.830"></a>
-<span class="sourceLineNo">831</span>      this.masterServices = masterServices;<a name="line.831"></a>
-<span class="sourceLineNo">832</span>    }<a name="line.832"></a>
-<span class="sourceLineNo">833</span><a name="line.833"></a>
-<span class="sourceLineNo">834</span>    @Override<a name="line.834"></a>
-<span class="sourceLineNo">835</span>    Cluster.Action generate(Cluster cluster) {<a name="line.835"></a>
-<span class="sourceLineNo">836</span>      if (this.masterServices == null) {<a name="line.836"></a>
-<span class="sourceLineNo">837</span>        int thisServer = pickRandomServer(cluster);<a name="line.837"></a>
-<span class="sourceLineNo">838</span>        // Pick the other server<a name="line.838"></a>
-<span class="sourceLineNo">839</span>        int otherServer = pickOtherRandomServer(cluster, thisServer);<a name="line.839"></a>
-<span class="sourceLineNo">840</span>        return pickRandomRegions(cluster, thisServer, otherServer);<a name="line.840"></a>
-<span class="sourceLineNo">841</span>      }<a name="line.841"></a>
-<span class="sourceLineNo">842</span><a name="line.842"></a>
-<span class="sourceLineNo">843</span>      // Randomly iterate through regions until you find one that is not on ideal host<a name="line.843"></a>
-<span class="sourceLineNo">844</span>      for (int region : getRandomIterationOrder(cluster.numRegions)) {<a name="line.844"></a>
-<span class="sourceLineNo">845</span>        int currentServer = cluster.regionIndexToServerIndex[region];<a name="line.845"></a>
-<span class="sourceLineNo">846</span>        if (currentServer != cluster.getOrComputeRegionsToMostLocalEntities(LocalityType.SERVER)[region]) {<a name="line.846"></a>
-<span class="sourceLineNo">847</span>          Optional&lt;Action&gt; potential = tryMoveOrSwap(<a name="line.847"></a>
-<span class="sourceLineNo">848</span>              cluster,<a name="line.848"></a>
-<span class="sourceLineNo">849</span>              currentServer,<a name="line.849"></a>
-<span class="sourceLineNo">850</span>              region,<a name="line.850"></a>
-<span class="sourceLineNo">851</span>              cluster.getOrComputeRegionsToMostLocalEntities(LocalityType.SERVER)[region]<a name="line.851"></a>
-<span class="sourceLineNo">852</span>          );<a name="line.852"></a>
-<span class="sourceLineNo">853</span>          if (potential.isPresent()) {<a name="line.853"></a>
-<span class="sourceLineNo">854</span>            return potential.get();<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>      }<a name="line.857"></a>
-<span class="sourceLineNo">858</span>      return Cluster.NullAction;<a name="line.858"></a>
-<span class="sourceLineNo">859</span>    }<a name="line.859"></a>
-<span class="sourceLineNo">860</span><a name="line.860"></a>
-<span class="sourceLineNo">861</span>    /**<a name="line.861"></a>
-<span class="sourceLineNo">862</span>     * Try to generate a move/swap fromRegion between fromServer and toServer such that locality is improved.<a name="line.862"></a>
-<span class="sourceLineNo">863</span>     * Returns empty optional if no move can be found<a name="line.863"></a>
-<span class="sourceLineNo">864</span>     */<a name="line.864"></a>
-<span class="sourceLineNo">865</span>    private Optional&lt;Action&gt; tryMoveOrSwap(Cluster cluster,<a name="line.865"></a>
-<span class="sourceLineNo">866</span>                                           int fromServer,<a name="line.866"></a>
-<span class="sourceLineNo">867</span>                                           int fromRegion,<a name="line.867"></a>
-<span class="sourceLineNo">868</span>                                           int toServer) {<a name="line.868"></a>
-<span class="sourceLineNo">869</span>      // Try move first. We know apriori fromRegion has the highest locality on toServer<a name="line.869"></a>
-<span class="sourceLineNo">870</span>      if (cluster.serverHasTooFewRegions(toServer)) {<a name="line.870"></a>
-<span class="sourceLineNo">871</span>        return Optional.of(getAction(fromServer, fromRegion, toServer, -1));<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>      // Compare locality gain/loss from swapping fromRegion with regions on toServer<a name="line.874"></a>
-<span class="sourceLineNo">875</span>      double fromRegionLocalityDelta =<a name="line.875"></a>
-<span class="sourceLineNo">876</span>          getWeightedLocality(cluster, fromRegion, toServer) - getWeightedLocality(cluster, fromRegion, fromServer);<a name="line.876"></a>
-<span class="sourceLineNo">877</span>      for (int toRegionIndex : getRandomIterationOrder(cluster.regionsPerServer[toServer].length)) {<a name="line.877"></a>
-<span class="sourceLineNo">878</span>        int toRegion = cluster.regionsPerServer[toServer][toRegionIndex];<a name="line.878"></a>
-<span class="sourceLineNo">879</span>        double toRegionLocalityDelta =<a name="line.879"></a>
-<span class="sourceLineNo">880</span>            getWeightedLocality(cluster, toRegion, fromServer) - getWeightedLocality(cluster, toRegion, toServer);<a name="line.880"></a>
-<span class="sourceLineNo">881</span>        // If locality would remain neutral or improve, attempt the swap<a name="line.881"></a>
-<span class="sourceLineNo">882</span>        if (fromRegionLocalityDelta + toRegionLocalityDelta &gt;= 0) {<a name="line.882"></a>
-<span class="sourceLineNo">883</span>          return Optional.of(getAction(fromServer, fromRegion, toServer, toRegion));<a name="line.883"></a>
-<span class="sourceLineNo">884</span>        }<a name="line.884"></a>
-<span class="sourceLineNo">885</span>      }<a name="line.885"></a>
-<span class="sourceLineNo">886</span><a name="line.886"></a>
-<span class="sourceLineNo">887</span>      return Optional.absent();<a name="line.887"></a>
-<span class="sourceLineNo">888</span>    }<a name="line.888"></a>
-<span class="sourceLineNo">889</span><a name="line.889"></a>
-<span class="sourceLineNo">890</span>    private double getWeightedLocality(Cluster cluster, int region, int server) {<a name="line.890"></a>
-<span class="sourceLineNo">891</span>      return cluster.getOrComputeWeightedLocality(region, server, LocalityType.SERVER);<a name="line.891"></a>
-<span class="sourceLineNo">892</span>    }<a name="line.892"></a>
-<span class="sourceLineNo">893</span><a name="line.893"></a>
-<span class="sourceLineNo">894</span>    void setServices(MasterServices services) {<a name="line.894"></a>
-<span class="sourceLineNo">895</span>      this.masterServices = services;<a name="line.895"></a>
-<span class="sourceLineNo">896</span>    }<a name="line.896"></a>
-<span class="sourceLineNo">897</span>  }<a name="line.897"></a>
-<span class="sourceLineNo">898</span><a name="line.898"></a>
-<span class="sourceLineNo">899</span>  /**<a name="line.899"></a>
-<span class="sourceLineNo">900</span>   * Generates candidates which moves the replicas out of the region server for<a name="line.900"></a>
-<span class="sourceLineNo">901</span>   * co-hosted region replicas<a name="line.901"></a>
-<span class="sourceLineNo">902</span>   */<a name="line.902"></a>
-<span class="sourceLineNo">903</span>  static class RegionReplicaCandidateGenerator extends CandidateGenerator {<a name="line.903"></a>
-<span class="sourceLineNo">904</span><a name="line.904"></a>
-<span class="sourceLineNo">905</span>    RandomCandidateGenerator randomGenerator = new RandomCandidateGenerator();<a name="line.905"></a>
+<span class="sourceLineNo">830</span>    private MasterServices masterServices;<a name="line.830"></a>
+<span class="sourceLineNo">831</span><a name="line.831"></a>
+<span class="sourceLineNo">832</span>    LocalityBasedCandidateGenerator(MasterServices masterServices) {<a name="line.832"></a>
+<span class="sourceLineNo">833</span>      this.masterServices = masterServices;<a name="line.833"></a>
+<span class="sourceLineNo">834</span>    }<a name="line.834"></a>
+<span class="sourceLineNo">835</span><a name="line.835"></a>
+<span class="sourceLineNo">836</span>    @Override<a name="line.836"></a>
+<span class="sourceLineNo">837</span>    Cluster.Action generate(Cluster cluster) {<a name="line.837"></a>
+<span class="sourceLineNo">838</span>      if (this.masterServices == null) {<a name="line.838"></a>
+<span class="sourceLineNo">839</span>        int thisServer = pickRandomServer(cluster);<a name="line.839"></a>
+<span class="sourceLineNo">840</span>        // Pick the other server<a name="line.840"></a>
+<span class="sourceLineNo">841</span>        int otherServer = pickOtherRandomServer(cluster, thisServer);<a name="line.841"></a>
+<span class="sourceLineNo">842</span>        return pickRandomRegions(cluster, thisServer, otherServer);<a name="line.842"></a>
+<span class="sourceLineNo">843</span>      }<a name="line.843"></a>
+<span class="sourceLineNo">844</span><a name="line.844"></a>
+<span class="sourceLineNo">845</span>      // Randomly iterate through regions until you find one that is not on ideal host<a name="line.845"></a>
+<span class="sourceLineNo">846</span>      for (int region : getRandomIterationOrder(cluster.numRegions)) {<a name="line.846"></a>
+<span class="sourceLineNo">847</span>        int currentServer = cluster.regionIndexToServerIndex[region];<a name="line.847"></a>
+<span class="sourceLineNo">848</span>        if (currentServer != cluster.getOrComputeRegionsToMostLocalEntities(LocalityType.SERVER)[region]) {<a name="line.848"></a>
+<span class="sourceLineNo">849</span>          Optional&lt;Action&gt; potential = tryMoveOrSwap(<a name="line.849"></a>
+<span class="sourceLineNo">850</span>              cluster,<a name="line.850"></a>
+<span class="sourceLineNo">851</span>              currentServer,<a name="line.851"></a>
+<span class="sourceLineNo">852</span>              region,<a name="line.852"></a>
+<span class="sourceLineNo">853</span>              cluster.getOrComputeRegionsToMostLocalEntities(LocalityType.SERVER)[region]<a name="line.853"></a>
+<span class="sourceLineNo">854</span>          );<a name="line.854"></a>
+<span class="sourceLineNo">855</span>          if (potential.isPresent()) {<a name="line.855"></a>
+<span class="sourceLineNo">856</span>            return potential.get();<a name="line.856"></a>
+<span class="sourceLineNo">857</span>          }<a name="line.857"></a>
+<span class="sourceLineNo">858</span>        }<a name="line.858"></a>
+<span class="sourceLineNo">859</span>      }<a name="line.859"></a>
+<span class="sourceLineNo">860</span>      return Cluster.NullAction;<a name="line.860"></a>
+<span class="sourceLineNo">861</span>    }<a name="line.861"></a>
+<span class="sourceLineNo">862</span><a name="line.862"></a>
+<span class="sourceLineNo">863</span>    /**<a name="line.863"></a>
+<span class="sourceLineNo">864</span>     * Try to generate a move/swap fromRegion between fromServer and toServer such that locality is improved.<a name="line.864"></a>
+<span class="sourceLineNo">865</span>     * Returns empty optional if no move can be found<a name="line.865"></a>
+<span class="sourceLineNo">866</span>     */<a name="line.866"></a>
+<span class="sourceLineNo">867</span>    private Optional&lt;Action&gt; tryMoveOrSwap(Cluster cluster,<a name="line.867"></a>
+<span class="sourceLineNo">868</span>                                           int fromServer,<a name="line.868"></a>
+<span class="sourceLineNo">869</span>                                           int fromRegion,<a name="line.869"></a>
+<span class="sourceLineNo">870</span>                                           int toServer) {<a name="line.870"></a>
+<span class="sourceLineNo">871</span>      // Try move first. We know apriori fromRegion has the highest locality on toServer<a name="line.871"></a>
+<span class="sourceLineNo">872</span>      if (cluster.serverHasTooFewRegions(toServer)) {<a name="line.872"></a>
+<span class="sourceLineNo">873</span>        return Optional.of(getAction(fromServer, fromRegion, toServer, -1));<a name="line.873"></a>
+<span class="sourceLineNo">874</span>      }<a name="line.874"></a>
+<span class="sourceLineNo">875</span><a name="line.875"></a>
+<span class="sourceLineNo">876</span>      // Compare locality gain/loss from swapping fromRegion with regions on toServer<a name="line.876"></a>
+<span class="sourceLineNo">877</span>      double fromRegionLocalityDelta =<a name="line.877"></a>
+<span class="sourceLineNo">878</span>          getWeightedLocality(cluster, fromRegion, toServer) - getWeightedLocality(cluster, fromRegion, fromServer);<a name="line.878"></a>
+<span class="sourceLineNo">879</span>      for (int toRegionIndex : getRandomIterationOrder(cluster.regionsPerServer[toServer].length)) {<a name="line.879"></a>
+<span class="sourceLineNo">880</span>        int toRegion = cluster.regionsPerServer[toServer][toRegionIndex];<a name="line.880"></a>
+<span class="sourceLineNo">881</span>        double toRegionLocalityDelta =<a name="line.881"></a>
+<span class="sourceLineNo">882</span>            getWeightedLocality(cluster, toRegion, fromServer) - getWeightedLocality(cluster, toRegion, toServer);<a name="line.882"></a>
+<span class="sourceLineNo">883</span>        // If locality would remain neutral or improve, attempt the swap<a name="line.883"></a>
+<span class="sourceLineNo">884</span>        if (fromRegionLocalityDelta + toRegionLocalityDelta &gt;= 0) {<a name="line.884"></a>
+<span class="sourceLineNo">885</span>          return Optional.of(getAction(fromServer, fromRegion, toServer, toRegion));<a name="line.885"></a>
+<span class="sourceLineNo">886</span>        }<a name="line.886"></a>
+<span class="sourceLineNo">887</span>      }<a name="line.887"></a>
+<span class="sourceLineNo">888</span><a name="line.888"></a>
+<span class="sourceLineNo">889</span>      return Optional.absent();<a name="line.889"></a>
+<span class="sourceLineNo">890</span>    }<a name="line.890"></a>
+<span class="sourceLineNo">891</span><a name="line.891"></a>
+<span class="sourceLineNo">892</span>    private double getWeightedLocality(Cluster cluster, int region, int server) {<a name="line.892"></a>
+<span class="sourceLineNo">893</span>      return cluster.getOrComputeWeightedLocality(region, server, LocalityType.SERVER);<a name="line.893"></a>
+<span class="sourceLineNo">894</span>    }<a name="line.894"></a>
+<span class="sourceLineNo">895</span><a name="line.895"></a>
+<span class="sourceLineNo">896</span>    void setServices(MasterServices services) {<a name="line.896"></a>
+<span class="sourceLineNo">897</span>      this.masterServices = services;<a name="line.897"></a>
+<span class="sourceLineNo">898</span>    }<a name="line.898"></a>
+<span class="sourceLineNo">899</span>  }<a name="line.899"></a>
+<span class="sourceLineNo">900</span><a name="line.900"></a>
+<span class="sourceLineNo">901</span>  /**<a name="line.901"></a>
+<span class="sourceLineNo">902</span>   * Generates candidates which moves the replicas out of the region server for<a name="line.902"></a>
+<span class="sourceLineNo">903</span>   * co-hosted region replicas<a name="line.903"></a>
+<span class="sourceLineNo">904</span>   */<a name="line.904"></a>
+<span class="sourceLineNo">905</span>  static class RegionReplicaCandidateGenerator extends CandidateGenerator {<a name="line.905"></a>
 <span class="sourceLineNo">906</span><a name="line.906"></a>
-<span class="sourceLineNo">907</span>    /**<a name="line.907"></a>
-<span class="sourceLineNo">908</span>     * Randomly select one regionIndex out of all region replicas co-hosted in the same group<a name="line.908"></a>
-<span class="sourceLineNo">909</span>     * (a group is a server, host or rack)<a name="line.909"></a>
-<span class="sourceLineNo">910</span>     * @param primariesOfRegionsPerGroup either Cluster.primariesOfRegionsPerServer,<a name="line.910"></a>
-<span class="sourceLineNo">911</span>     * primariesOfRegionsPerHost or primariesOfRegionsPerRack<a name="line.911"></a>
-<span class="sourceLineNo">912</span>     * @param regionsPerGroup either Cluster.regionsPerServer, regionsPerHost or regionsPerRack<a name="line.912"></a>
-<span class="sourceLineNo">913</span>     * @param regionIndexToPrimaryIndex Cluster.regionsIndexToPrimaryIndex<a name="line.913"></a>
-<span class="sourceLineNo">914</span>     * @return a regionIndex for the selected primary or -1 if there is no co-locating<a name="line.914"></a>
-<span class="sourceLineNo">915</span>     */<a name="line.915"></a>
-<span class="sourceLineNo">916</span>    int selectCoHostedRegionPerGroup(int[] primariesOfRegionsPerGroup, int[] regionsPerGroup<a name="line.916"></a>
-<span class="sourceLineNo">917</span>        , int[] regionIndexToPrimaryIndex) {<a name="line.917"></a>
-<span class="sourceLineNo">918</span>      int currentPrimary = -1;<a name="line.918"></a>
-<span class="sourceLineNo">919</span>      int currentPrimaryIndex = -1;<a name="line.919"></a>
-<span class="sourceLineNo">920</span>      int selectedPrimaryIndex = -1;<a name="line.920"></a>
-<span class="sourceLineNo">921</span>      double currentLargestRandom = -1;<a name="line.921"></a>
-<span class="sourceLineNo">922</span>      // primariesOfRegionsPerGroup is a sorted array. Since it contains the primary region<a name="line.922"></a>
-<span class="sourceLineNo">923</span>      // ids for the regions hosted in server, a consecutive repetition means that replicas<a name="line.923"></a>
-<span class="sourceLineNo">924</span>      // are co-hosted<a name="line.924"></a>
-<span class="sourceLineNo">925</span>      for (int j = 0; j &lt;= primariesOfRegionsPerGroup.length; j++) {<a name="line.925"></a>
-<span class="sourceLineNo">926</span>        int primary = j &lt; primariesOfRegionsPerGroup.length<a name="line.926"></a>
-<span class="sourceLineNo">927</span>            ? primariesOfRegionsPerGroup[j] : -1;<a name="line.927"></a>
-<span class="sourceLineNo">928</span>        if (primary != currentPrimary) { // check for whether we see a new primary<a name="line.928"></a>
-<span class="sourceLineNo">929</span>          int numReplicas = j - currentPrimaryIndex;<a name="line.929"></a>
-<span class="sourceLineNo">930</span>          if (numReplicas &gt; 1) { // means consecutive primaries, indicating co-location<a name="line.930"></a>
-<span class="sourceLineNo">931</span>            // decide to select this primary region id or not<a name="line.931"></a>
-<span class="sourceLineNo">932</span>            double currentRandom = RANDOM.nextDouble();<a name="line.932"></a>
-<span class="sourceLineNo">933</span>            // we don't know how many region replicas are co-hosted, we will randomly select one<a name="line.933"></a>
-<span class="sourceLineNo">934</span>            // using reservoir sampling (http://gregable.com/2007/10/reservoir-sampling.html)<a name="line.934"></a>
-<span class="sourceLineNo">935</span>            if (currentRandom &gt; currentLargestRandom) {<a name="line.935"></a>
-<span class="sourceLineNo">936</span>              selectedPrimaryIndex = currentPrimary;<a name="line.936"></a>
-<span class="sourceLineNo">937</span>              currentLargestRandom = currentRandom;<a name="line.937"></a>
-<span class="sourceLineNo">938</span>            }<a name="line.938"></a>
-<span class="sourceLineNo">939</span>          }<a name="line.939"></a>
-<span class="sourceLineNo">940</span>          currentPrimary = primary;<a name="line.940"></a>
-<span class="sourceLineNo">941</span>          currentPrimaryIndex = j;<a name="line.941"></a>
-<span class="sourceLineNo">942</span>        }<a name="line.942"></a>
-<span class="sourceLineNo">943</span>      }<a name="line.943"></a>
-<span class="sourceLineNo">944</span><a name="line.944"></a>
-<span class="sourceLineNo">945</span>      // we have found the primary id for the region to move. Now find the actual regionIndex<a name="line.945"></a>
-<span class="sourceLineNo">946</span>      // with the given primary, prefer to move the secondary region.<a name="line.946"></a>
-<span class="sourceLineNo">947</span>      for (int j = 0; j &lt; regionsPerGroup.length; j++) {<a name="line.947"></a>
-<span class="sourceLineNo">948</span>        int regionIndex = regionsPerGroup[j];<a name="line.948"></a>
-<span class="sourceLineNo">949</span>        if (selectedPrimaryIndex == regionIndexToPrimaryIndex[regionIndex]) {<a name="line.949"></a>
-<span class="sourceLineNo">950</span>          // always move the secondary, not the primary<a name="line.950"></a>
-<span class="sourceLineNo">951</span>          if (selectedPrimaryIndex != regionIndex) {<a name="line.951"></a>
-<span class="sourceLineNo">952</span>            return regionIndex;<a name="line.952"></a>
-<span class="sourceLineNo">953</span>          }<a name="line.953"></a>
-<span class="sourceLineNo">954</span>        }<a name="line.954"></a>
-<span class="sourceLineNo">955</span>      }<a name="line.955"></a>
-<span class="sourceLineNo">956</span>      return -1;<a name="line.956"></a>
-<span class="sourceLineNo">957</span>    }<a name="line.957"></a>
-<span class="sourceLineNo">958</span><a name="line.958"></a>
-<span class="sourceLineNo">959</span>    @Override<a name="line.959"></a>
-<span class="sourceLineNo">960</span>    Cluster.Action generate(Cluster cluster) {<a name="line.960"></a>
-<span class="sourceLineNo">961</span>      int serverIndex = pickRandomServer(cluster);<a name="line.961"></a>
-<span class="sourceLineNo">962</span>      if (cluster.numServers &lt;= 1 || serverIndex == -1) {<a name="line.962"></a>
-<span class="sourceLineNo">963</span>        return Cluster.NullAction;<a name="line.963"></a>
-<span class="sourceLineNo">964</span>      }<a name="line.964"></a>
-<span class="sourceLineNo">965</span><a name="line.965"></a>
-<span class="sourceLineNo">966</span>      int regionIndex = selectCoHostedRegionPerGroup(<a name="line.966"></a>
-<span class="sourceLineNo">967</span>        cluster.primariesOfRegionsPerServer[serverIndex],<a name="line.967"></a>
-<span class="sourceLineNo">968</span>        cluster.regionsPerServer[serverIndex],<a name="line.968"></a>
-<span class="sourceLineNo">969</span>        cluster.regionIndexToPrimaryIndex);<a name="line.969"></a>
-<span class="sourceLineNo">970</span><a name="line.970"></a>
-<span class="sourceLineNo">971</span>      // if there are no pairs of region replicas co-hosted, default to random generator<a name="line.971"></a>
-<span class="sourceLineNo">972</span>      if (regionIndex == -1) {<a name="line.972"></a>
-<span class="sourceLineNo">973</span>        // default to randompicker<a name="line.973"></a>
-<span class="sourceLineNo">974</span>        return randomGenerator.generate(cluster);<a name="line.974"></a>
-<span class="sourceLineNo">975</span>      }<a name="line.975"></a>
-<span class="sourceLineNo">976</span><a name="line.976"></a>
-<span class="sourceLineNo">977</span>      int toServerIndex = pickOtherRandomServer(cluster, serverIndex);<a name="line.977"></a>
-<span class="sourceLineNo">978</span>      int toRegionIndex = pickRandomRegion(cluster, toServerIndex, 0.9f);<a name="line.978"></a>
-<span class="sourceLineNo">979</span>      return getAction(serverIndex, regionIndex, toServerIndex, toRegionIndex);<a name="line.979"></a>
-<span class="sourceLineNo">980</span>    }<a name="line.980"></a>
-<span class="sourceLineNo">981</span>  }<a name="line.981"></a>
-<span class="sourceLineNo">982</span><a name="line.982"></a>
-<span class="sourceLineNo">983</span>  /**<a name="line.983"></a>
-<span class="sourceLineNo">984</span>   * Generates candidates which moves the replicas out of the rack for<a name="line.984"></a>
-<span class="sourceLineNo">985</span>   * co-hosted region replicas in the same rack<a name="line.985"></a>
-<span class="sourceLineNo">986</span>   */<a name="line.986"></a>
-<span class="sourceLineNo">987</span>  static class RegionReplicaRackCandidateGenerator extends RegionReplicaCandidateGenerator {<a name="line.987"></a>
-<span class="sourceLineNo">988</span>    @Override<a name="line.988"></a>
-<span class="sourceLineNo">989</span>    Cluster.Action generate(Cluster cluster) {<a name="line.989"></a>
-<span class="sourceLineNo">990</span>      int rackIndex = pickRandomRack(cluster);<a name="line.990"></a>
-<span class="sourceLineNo">991</span>      if (cluster.numRacks &lt;= 1 || rackIndex == -1) {<a name="line.991"></a>
-<span class="sourceLineNo">992</span>        return super.generate(cluster);<a name="line.992"></a>
-<span class="sourceLineNo">993</span>      }<a name="line.993"></a>
-<span class="sourceLineNo">994</span><a name="line.994"></a>
-<span class="sourceLineNo">995</span>      int regionIndex = selectCoHostedRegionPerGroup(<a name="line.995"></a>
-<span class="sourceLineNo">996</span>        cluster.primariesOfRegionsPerRack[rackIndex],<a name="line.996"></a>
-<span class="sourceLineNo">997</span>        cluster.regionsPerRack[rackIndex],<a name="line.997"></a>
-<span class="sourceLineNo">998</span>        cluster.regionIndexToPrimaryIndex);<a name="line.998"></a>
-<span class="sourceLineNo">999</span><a name="line.999"></a>
-<span class="sourceLineNo">1000</span>      // if there are no pairs of region replicas co-hosted, default to random generator<a name="line.1000"></a>
-<span class="sourceLineNo">1001</span>      if (regionIndex == -1) {<a name="line.1001"></a>
-<span class="sourceLineNo">1002</span>        // default to randompicker<a name="line.1002"></a>
-<span class="sourceLineNo">1003</span>        return randomGenerator.generate(cluster);<a name="line.1003"></a>
-<span class="sourceLineNo">1004</span>      }<a name="line.1004"></a>
-<span class="sourceLineNo">1005</span><a name="line.1005"></a>
-<span class="sourceLineNo">1006</span>      int serverIndex = cluster.regionIndexToServerIndex[regionIndex];<a name="line.1006"></a>
-<span class="sourceLineNo">1007</span>      int toRackIndex = pickOtherRandomRack(cluster, rackIndex);<a name="line.1007"></a>
-<span class="sourceLineNo">1008</span><a name="line.1008"></a>
-<span class="sourceLineNo">1009</span>      int rand = RANDOM.nextInt(cluster.serversPerRack[toRackIndex].length);<a name="line.1009"></a>
-<span class="sourceLineNo">1010</span>      int toServerIndex = cluster.serversPerRack[toRackIndex][rand];<a name="line.1010"></a>
-<span class="sourceLineNo">1011</span>      int toRegionIndex = pickRandomRegion(cluster, toServerIndex, 0.9f);<a name="line.1011"></a>
-<span class="sourceLineNo">1012</span>      return getAction(serverIndex, regionIndex, toServerIndex, toRegionIndex);<a name="line.1012"></a>
-<span class="sourceLineNo">1013</span>    }<a name="line.1013"></a>
-<span class="sourceLineNo">1014</span>  }<a name="line.1014"></a>
-<span class="sourceLineNo">1015</span><a name="line.1015"></a>
-<span class="sourceLineNo">1016</span>  /**<a name="line.1016"></a>
-<span class="sourceLineNo">1017</span>   * Base class of StochasticLoadBalancer's Cost Functions.<a name="line.1017"></a>
-<span class="sourceLineNo">1018</span>   */<a name="line.1018"></a>
-<span class="sourceLineNo">1019</span>  public abstract static class CostFunction {<a name="line.1019"></a>
-<span class="sourceLineNo">1020</span><a name="line.1020"></a>
-<span class="sourceLineNo">1021</span>    private float multiplier = 0;<a name="line.1021"></a>
+<span class="sourceLineNo">907</span>    RandomCandidateGenerator randomGenerator = new RandomCandidateGenerator();<a name="line.907"></a>
+<span class="sourceLineNo">908</span><a name="line.908"></a>
+<span class="sourceLineNo">909</span>    /**<a name="line.909"></a>
+<span class="sourceLineNo">910</span>     * Randomly select one regionIndex out of all region replicas co-hosted in the same group<a name="line.910"></a>
+<span class="sourceLineNo">911</span>     * (a group is a server, host or rack)<a name="line.911"></a>
+<span class="sourceLineNo">912</span>     * @param primariesOfRegionsPerGroup either Cluster.primariesOfRegionsPerServer,<a name="line.912"></a>
+<span class="sourceLineNo">913</span>     * primariesOfRegionsPerHost or primariesOfRegionsPerRack<a name="line.913"></a>
+<span class="sourceLineNo">914</span>     * @param regionsPerGroup either Cluster.regionsPerServer, regionsPerHost or regionsPerRack<a name="line.914"></a>
+<span class="sourceLineNo">915</span>     * @param regionIndexToPrimaryIndex Cluster.regionsIndexToPrimaryIndex<a name="line.915"></a>
+<span class="sourceLineNo">916</span>     * @return a regionIndex for the selected primary or -1 if there is no co-locating<a name="line.916"></a>
+<span class="sourceLineNo">917</span>     */<a name="line.917"></a>
+<span class="sourceLineNo">918</span>    int selectCoHostedRegionPerGroup(int[] primariesOfRegionsPerGroup, int[] regionsPerGroup<a name="line.918"></a>
+<span class="sourceLineNo">919</span>        , int[] regionIndexToPrimaryIndex) {<a name="line.919"></a>
+<span class="sourceLineNo">920</span>      int currentPrimary = -1;<a name="line.920"></a>
+<span class="sourceLineNo">921</span>      int currentPrimaryIndex = -1;<a name="line.921"></a>
+<span class="sourceLineNo">922</span>      int selectedPrimaryIndex = -1;<a name="line.922"></a>
+<span class="sourceLineNo">923</span>      double currentLargestRandom = -1;<a name="line.923"></a>
+<span class="sourceLineNo">924</span>      // primariesOfRegionsPerGroup is a sorted array. Since it contains the primary region<a name="line.924"></a>
+<span class="sourceLineNo">925</span>      // ids for the regions hosted in server, a consecutive repetition means that replicas<a name="line.925"></a>
+<span class="sourceLineNo">926</span>      // are co-hosted<a name="line.926"></a>
+<span class="sourceLineNo">927</span>      for (int j = 0; j &lt;= primariesOfRegionsPerGroup.length; j++) {<a name="line.927"></a>
+<span class="sourceLineNo">928</span>        int primary = j &lt; primariesOfRegionsPerGroup.length<a name="line.928"></a>
+<span class="sourceLineNo">929</span>            ? primariesOfRegionsPerGroup[j] : -1;<a name="line.929"></a>
+<span class="sourceLineNo">930</span>        if (primary != currentPrimary) { // check for whether we see a new primary<a name="line.930"></a>
+<span class="sourceLineNo">931</span>          int numReplicas = j - currentPrimaryIndex;<a name="line.931"></a>
+<span class="sourceLineNo">932</span>          if (numReplicas &gt; 1) { // means consecutive primaries, indicating co-location<a name="line.932"></a>
+<span class="sourceLineNo">933</span>            // decide to select this primary region id or not<a name="line.933"></a>
+<span class="sourceLineNo">934</span>            double currentRandom = RANDOM.nextDouble();<a name="line.934"></a>
+<span class="sourceLineNo">935</span>            // we don't know how many region replicas are co-hosted, we will randomly select one<a name="line.935"></a>
+<span class="sourceLineNo">936</span>            // using reservoir sampling (http://gregable.com/2007/10/reservoir-sampling.html)<a name="line.936"></a>
+<span class="sourceLineNo">937</span>            if (currentRandom &gt; currentLargestRandom) {<a name="line.937"></a>
+<span class="sourceLineNo">938</span>              selectedPrimaryIndex = currentPrimary;<a name="line.938"></a>
+<span class="sourceLineNo">939</span>              currentLargestRandom = currentRandom;<a name="line.939"></a>
+<span class="sourceLineNo">940</span>            }<a name="line.940"></a>
+<span class="sourceLineNo">941</span>          }<a name="line.941"></a>
+<span class="sourceLineNo">942</span>          currentPrimary = primary;<a name="line.942"></a>
+<span class="sourceLineNo">943</span>          currentPrimaryIndex = j;<a name="line.943"></a>
+<span class="sourceLineNo">944</span>        }<a name="line.944"></a>
+<span class="sourceLineNo">945</span>      }<a name="line.945"></a>
+<span class="sourceLineNo">946</span><a name="line.946"></a>
+<span class="sourceLineNo">947</span>      // we have found the primary id for the region to move. Now find the actual regionIndex<a name="line.947"></a>
+<span class="sourceLineNo">948</span>      // with the given primary, prefer to move the secondary region.<a name="line.948"></a>
+<span class="sourceLineNo">949</span>      for (int j = 0; j &lt; regionsPerGroup.length; j++) {<a name="line.949"></a>
+<span class="sourceLineNo">950</span>        int regionIndex = regionsPerGroup[j];<a name="line.950"></a>
+<span class="sourceLineNo">951</span>        if (selectedPrimaryIndex == regionIndexToPrimaryIndex[regionIndex]) {<a name="line.951"></a>
+<span class="sourceLineNo">952</span>          // always move the secondary, not the primary<a name="line.952"></a>
+<span class="sourceLineNo">953</span>          if (selectedPrimaryIndex != regionIndex) {<a name="line.953"></a>
+<span class="sourceLineNo">954</span>            return regionIndex;<a name="line.954"></a>
+<span class="sourceLineNo">955</span>          }<a name="line.955"></a>
+<span class="sourceLineNo">956</span>        }<a name="line.956"></a>
+<span class="sourceLineNo">957</span>      }<a name="line.957"></a>
+<span class="sourceLineNo">958</span>      return -1;<a name="line.958"></a>
+<span class="sourceLineNo">959</span>    }<a name="line.959"></a>
+<span class="sourceLineNo">960</span><a name="line.960"></a>
+<span class="sourceLineNo">961</span>    @Override<a name="line.961"></a>
+<span class="sourceLineNo">962</span>    Cluster.Action generate(Cluster cluster) {<a name="line.962"></a>
+<span class="sourceLineNo">963</span>      int serverIndex = pickRandomServer(cluster);<a name="line.963"></a>
+<span class="sourceLineNo">964</span>      if (cluster.numServers &lt;= 1 || serverIndex == -1) {<a name="line.964"></a>
+<span class="sourceLineNo">965</span>        return Cluster.NullAction;<a name="line.965"></a>
+<span class="sourceLineNo">966</span>      }<a name="line.966"></a>
+<span class="sourceLineNo">967</span><a name="line.967"></a>
+<span class="sourceLineNo">968</span>      int regionIndex = selectCoHostedRegionPerGroup(<a name="line.968"></a>
+<span class="sourceLineNo">969</span>        cluster.primariesOfRegionsPerServer[serverIndex],<a name="line.969"></a>
+<span class="sourceLineNo">970</span>        cluster.regionsPerServer[serverIndex],<a name="line.970"></a>
+<span class="sourceLineNo">971</span>        cluster.regionIndexToPrimaryIndex);<a name="line.971"></a>
+<span class="sourceLineNo">972</span><a name="line.972"></a>
+<span class="sourceLineNo">973</span>      // if there are no pairs of region replicas co-hosted, default to random generator<a name="line.973"></a>
+<span class="sourceLineNo">974</span>      if (regionIndex == -1) {<a name="line.974"></a>
+<span class="sourceLineNo">975</span>        // default to randompicker<a name="line.975"></a>
+<span class="sourceLineNo">976</span>        return randomGenerator.generate(cluster);<a name="line.976"></a>
+<span class="sourceLineNo">977</span>      }<a name="line.977"></a>
+<span class="sourceLineNo">978</span><a name="line.978"></a>
+<span class="sourceLineNo">979</span>      int toServerIndex = pickOtherRandomServer(cluster, serverIndex);<a name="line.979"></a>
+<span class="sourceLineNo">980</span>      int toRegionIndex = pickRandomRegion(cluster, toServerIndex, 0.9f);<a name="line.980"></a>
+<span class="sourceLineNo">981</span>      return getAction(serverIndex, regionIndex, toServerIndex, toRegionIndex);<a name="line.981"></a>
+<span class="sourceLineNo">982</span>    }<a name="line.982"></a>
+<span class="sourceLineNo">983</span>  }<a name="line.983"></a>
+<span class="sourceLineNo">984</span><a name="line.984"></a>
+<span class="sourceLineNo">985</span>  /**<a name="line.985"></a>
+<span class="sourceLineNo">986</span>   * Generates candidates which moves the replicas out of the rack for<a name="line.986"></a>
+<span class="sourceLineNo">987</span>   * co-hosted region replicas in the same rack<a name="line.987"></a>
+<span class="sourceLineNo">988</span>   */<a name="line.988"></a>
+<span class="sourceLineNo">989</span>  static class RegionReplicaRackCandidateGenerator extends RegionReplicaCandidateGenerator {<a name="line.989"></a>
+<span class="sourceLineNo">990</span>    @Override<a name="line.990"></a>
+<span class="sourceLineNo">991</span>    Cluster.Action generate(Cluster cluster) {<a name="line.991"></a>
+<span class="sourceLineNo">992</span>      int rackIndex = pickRandomRack(cluster);<a name="line.992"></a>
+<span class="sourceLineNo">993</span>      if (cluster.numRacks &lt;= 1 || rackIndex == -1) {<a name="line.993"></a>
+<span class="sourceLineNo">994</span>        return super.generate(cluster);<a name="line.994"></a>
+<span class="sourceLineNo">995</span>      }<a name="line.995"></a>
+<span class="sourceLineNo">996</span><a name="line.996"></a>
+<span class="sourceLineNo">997</span>      int regionIndex = selectCoHostedRegionPerGroup(<a name="line.997"></a>
+<span class="sourceLineNo">998</span>        cluster.primariesOfRegionsPerRack[rackIndex],<a name="line.998"></a>
+<span class="sourceLineNo">999</span>        cluster.regionsPerRack[rackIndex],<a name="line.999"></a>
+<span class="sourceLineNo">1000</span>        cluster.regionIndexToPrimaryIndex);<a name="line.1000"></a>
+<span class="sourceLineNo">1001</span><a name="line.1001"></a>
+<span class="sourceLineNo">1002</span>      // if there are no pairs of region replicas co-hosted, default to random generator<a name="line.1002"></a>
+<span class="sourceLineNo">1003</span>      if (regionIndex == -1) {<a name="line.1003"></a>
+<span class="sourceLineNo">1004</span>        // default to randompicker<a name="line.1004"></a>
+<span class="sourceLineNo">1005</span>        return randomGenerator.generate(cluster);<a name="line.1005"></a>
+<span class="sourceLineNo">1006</span>      }<a name="line.1006"></a>
+<span class="sourceLineNo">1007</span><a name="line.1007"></a>
+<span class="sourceLineNo">1008</span>      int serverIndex = cluster.regionIndexToServerIndex[regionIndex];<a name="line.1008"></a>
+<span class="sourceLineNo">1009</span>      int toRackIndex = pickOtherRandomRack(cluster, rackIndex);<a name="line.1009"></a>
+<span class="sourceLineNo">1010</span><a name="line.1010"></a>
+<span class="sourceLineNo">1011</span>      int rand = RANDOM.nextInt(cluster.serversPerRack[toRackIndex].length);<a name="line.1011"></a>
+<span class="sourceLineNo">1012</span>      int toServerIndex = cluster.serversPerRack[toRackIndex][rand];<a name="line.1012"></a>
+<span class="sourceLineNo">1013</span>      int toRegionIndex = pickRandomRegion(cluster, toServerIndex, 0.9f);<a name="line.1013"></a>
+<span class="sourceLineNo">1014</span>      return getAction(serverIndex, regionIndex, toServerIndex, toRegionIndex);<a name="line.1014"></a>
+<span class="sourceLineNo">1015</span>    }<a name="line.1015"></a>
+<span class="sourceLineNo">1016</span>  }<a name="line.1016"></a>
+<span class="sourceLineNo">1017</span><a name="line.1017"></a>
+<span class="sourceLineNo">1018</span>  /**<a name="line.1018"></a>
+<span class="sourceLineNo">1019</span>   * Base class of StochasticLoadBalancer's Cost Functions.<a name="line.1019"></a>
+<span class="sourceLineNo">1020</span>   */<a name="line.1020"></a>
+<span class="sourceLineNo">1021</span>  public abstract static class CostFunction {<a name="line.1021"></a>
 <span class="sourceLineNo">1022</span><a name="line.1022"></a>
-<span class="sourceLineNo">1023</span>    protected Cluster cluster;<a name="line.1023"></a>
+<span class="sourceLineNo">1023</span>    private float multiplier = 0;<a name="line.1023"></a>
 <span class="sourceLineNo">1024</span><a name="line.1024"></a>
-<span class="sourceLineNo">1025</span>    public CostFunction(Configuration c) {<a name="line.1025"></a>
-<span class="sourceLineNo">1026</span>    }<a name="line.1026"></a>
-<span class="sourceLineNo">1027</span><a name="line.1027"></a>
-<span class="sourceLineNo">1028</span>    boolean isNeeded() {<a name="line.1028"></a>
-<span class="sourceLineNo">1029</span>      return true;<a name="line.1029"></a>
-<span class="sourceLineNo">1030</span>    }<a name="line.1030"></a>
-<span class="sourceLineNo">1031</span>    float getMultiplier() {<a name="line.1031"></a>
-<span class="sourceLineNo">1032</span>      return multiplier;<a name="line.1032"></a>
-<span class="sourceLineNo">1033</span>    }<a name="line.1033"></a>
-<span class="sourceLineNo">1034</span><a name="line.1034"></a>
-<span class="sourceLineNo">1035</span>    void setMultiplier(float m) {<a name="line.1035"></a>
-<span class="sourceLineNo">1036</span>      this.multiplier = m;<a name="line.1036"></a>
-<span class="sourceLineNo">1037</span>    }<a name="line.1037"></a>
-<span class="sourceLineNo">1038</span><a name="line.1038"></a>
-<span class="sourceLineNo">1039</span>    /** Called once per LB invocation to give the cost function<a name="line.1039"></a>
-<span class="sourceLineNo">1040</span>     * to initialize it's state, and perform any costly calculation.<a name="line.1040"></a>
-<span class="sourceLineNo">1041</span>     */<a name="line.1041"></a>
-<span class="sourceLineNo">1042</span>    void init(Cluster cluster) {<a name="line.1042"></a>
-<span class="sourceLineNo">1043</span>      this.cluster = cluster;<a name="line.1043"></a>
-<span class="sourceLineNo">1044</span>    }<a name="line.1044"></a>
-<span class="sourceLineNo">1045</span><a name="line.1045"></a>
-<span class="sourceLineNo">1046</span>    /** Called once per cluster Action to give the cost function<a name="line.1046"></a>
-<span class="sourceLineNo">1047</span>     * an opportunity to update it's state. postAction() is always<a name="line.1047"></a>
-<span class="sourceLineNo">1048</span>     * called at least once before cost() is called with the cluster<a name="line.1048"></a>
-<span class="sourceLineNo">1049</span>     * that this action is performed on. */<a name="line.1049"></a>
-<span class="sourceLineNo">1050</span>    void postAction(Action action) {<a name="line.1050"></a>
-<span class="sourceLineNo">1051</span>      switch (action.type) {<a name="line.1051"></a>
-<span class="sourceLineNo">1052</span>      case NULL: break;<a name="line.1052"></a>
-<span class="sourceLineNo">1053</span>      case ASSIGN_REGION:<a name="line.1053"></a>
-<span class="sourceLineNo">1054</span>        AssignRegionAction ar = (AssignRegionAction) action;<a name="line.1054"></a>
-<span class="sourceLineNo">1055</span>        regionMoved(ar.region, -1, ar.server);<a name="line.1055"></a>
-<span class="sourceLineNo">1056</span>        break;<a name="line.1056"></a>
-<span class="sourceLineNo">1057</span>      case MOVE_REGION:<a name="line.1057"></a>
-<span class="sourceLineNo">1058</span>        MoveRegionAction mra = (MoveRegionAction) action;<a name="line.1058"></a>
-<span class="sourceLineNo">1059</span>        regionMoved(mra.region, mra.fromServer, mra.toServer);<a name="line.1059"></a>
-<span class="sourceLineNo">1060</span>        break;<a name="line.1060"></a>
-<span class="sourceLineNo">1061</span>      case SWAP_REGIONS:<a name="line.1061"></a>
-<span class="sourceLineNo">1062</span>        SwapRegionsAction a = (SwapRegionsAction) action;<a name="line.1062"></a>
-<span class="sourceLineNo">1063</span>        regionMoved(a.fromRegion, a.fromServer, a.toServer);<a name="line.1063"></a>
-<span class="sourceLineNo">1064</span>        regionMoved(a.toRegion, a.toServer, a.fromServer);<a name="line.1064"></a>
-<span class="sourceLineNo">1065</span>        break;<a name="line.1065"></a>
-<span class="sourceLineNo">1066</span>      default:<a name="line.1066"></a>
-<span class="sourceLineNo">1067</span>        throw new RuntimeException("Uknown action:" + action.type);<a name="line.1067"></a>
-<span class="sourceLineNo">1068</span>      }<a name="line.1068"></a>
-<span class="sourceLineNo">1069</span>    }<a name="line.1069"></a>
-<span class="sourceLineNo">1070</span><a name="line.1070"></a>
-<span class="sourceLineNo">1071</span>    protected void regionMoved(int region, int oldServer, int newServer) {<a name="line.1071"></a>
-<span class="sourceLineNo">1072</span>    }<a name="line.1072"></a>
-<span class="sourceLineNo">1073</span><a name="line.1073"></a>
-<span class="sourceLineNo">1074</span>    protected abstract double cost();<a name="line.1074"></a>
+<span class="sourceLineNo">1025</span>    protected Cluster cluster;<a name="line.1025"></a>
+<span class="sourceLineNo">1026</span><a name="line.1026"></a>
+<span class="sourceLineNo">1027</span>    public CostFunction(Configuration c) {<a name="line.1027"></a>
+<span class="sourceLineNo">1028</span>    }<a name="line.1028"></a>
+<span class="sourceLineNo">1029</span><a name="line.1029"></a>
+<span class="sourceLineNo">1030</span>    boolean isNeeded() {<a name="line.1030"></a>
+<span class="sourceLineNo">1031</span>      return true;<a name="line.1031"></a>
+<span class="sourceLineNo">1032</span>    }<a name="line.1032"></a>
+<span class="sourceLineNo">1033</span>    float getMultiplier() {<a name="line.1033"></a>
+<span class="sourceLineNo">1034</span>      return multiplier;<a name="line.1034"></a>
+<span class="sourceLineNo">1035</span>    }<a name="line.1035"></a>
+<span class="sourceLineNo">1036</span><a name="line.1036"></a>
+<span class="sourceLineNo">1037</span>    void setMultiplier(float m) {<a name="line.1037"></a>
+<span class="sourceLineNo">1038</span>      this.multiplier = m;<a name="line.1038"></a>
+<span class="sourceLineNo">1039</span>    }<a name="line.1039"></a>
+<span class="sourceLineNo">1040</span><a name="line.1040"></a>
+<span class="sourceLineNo">1041</span>    /** Called once per LB invocation to give the cost function<a name="line.1041"></a>
+<span class="sourceLineNo">1042</span>     * to initialize it's state, and perform any costly calculation.<a name="line.1042"></a>
+<span class="sourceLineNo">1043</span>     */<a name="line.1043"></a>
+<span class="sourceLineNo">1044</span>    void init(Cluster cluster) {<a name="line.1044"></a>
+<span class="sourceLineNo">1045</span>      this.cluster = cluster;<a name="line.1045"></a>
+<span class="sourceLineNo">1046</span>    }<a name="line.1046"></a>
+<span class="sourceLineNo">1047</span><a name="line.1047"></a>
+<span class="sourceLineNo">1048</span>    /** Called once per cluster Action to give the cost function<a name="line.1048"></a>
+<span class="sourceLineNo">1049</span>     * an opportunity to update it's state. postAction() is always<a name="line.1049"></a>
+<span class="sourceLineNo">1050</span>     * called at least once before cost() is called with the cluster<a name="line.1050"></a>
+<span class="sourceLineNo">1051</span>     * that this action is performed on. */<a name="line.1051"></a>
+<span class="sourceLineNo">1052</span>    void postAction(Action action) {<a name="line.1052"></a>
+<span class="sourceLineNo">1053</span>      switch (action.type) {<a name="line.1053"></a>
+<span class="sourceLineNo">1054</span>      case NULL: break;<a name="line.1054"></a>
+<span class="sourceLineNo">1055</span>      case ASSIGN_REGION:<a name="line.1055"></a>
+<span class="sourceLineNo">1056</span>        AssignRegionAction ar = (AssignRegionAction) action;<a name="line.1056"></a>
+<span class="sourceLineNo">1057</span>        regionMoved(ar.region, -1, ar.server);<a name="line.1057"></a>
+<span class="sourceLineNo">1058</span>        break;<a name="line.1058"></a>
+<span class="sourceLineNo">1059</span>      case MOVE_REGION:<a name="line.1059"></a>
+<span class="sourceLineNo">1060</span>        MoveRegionAction mra = (MoveRegionAction) action;<a name="line.1060"></a>
+<span class="sourceLineNo">1061</span>        regionMoved(mra.region, mra.fromServer, mra.toServer);<a name="line.1061"></a>
+<span class="sourceLineNo">1062</span>        break;<a name="line.1062"></a>
+<span class="sourceLineNo">1063</span>      case SWAP_REGIONS:<a name="line.1063"></a>
+<span class="sourceLineNo">1064</span>        SwapRegionsAction a = (SwapRegionsAction) action;<a name="line.1064"></a>
+<span class="sourceLineNo">1065</span>        regionMoved(a.fromRegion, a.fromServer, a.toServer);<a name="line.1065"></a>
+<span class="sourceLineNo">1066</span>        regionMoved(a.toRegion, a.toServer, a.fromServer);<a name="line.1066"></a>
+<span class="sourceLineNo">1067</span>        break;<a name="line.1067"></a>
+<span class="sourceLineNo">1068</span>      default:<a name="line.1068"></a>
+<span class="sourceLineNo">1069</span>        throw new RuntimeException("Uknown action:" + action.type);<a name="line.1069"></a>
+<span class="sourceLineNo">1070</span>      }<a name="line.1070"></a>
+<span class="sourceLineNo">1071</span>    }<a name="line.1071"></a>
+<span class="sourceLineNo">1072</span><a name="line.1072"></a>
+<span class="sourceLineNo">1073</span>    protected void regionMoved(int region, int oldServer, int newServer) {<a name="line.1073"></a>
+<span class="sourceLineNo">1074</span>    }<a name="line.1074"></a>
 <span class="sourceLineNo">1075</span><a name="line.1075"></a>
-<span class="sourceLineNo">1076</span>    @SuppressWarnings("checkstyle:linelength")<a name="line.1076"></a>
-<span class="sourceLineNo">1077</span>    /**<a name="line.1077"></a>
-<span class="sourceLineNo">1078</span>     * Function to compute a scaled cost using<a name="line.1078"></a>
-<span class="sourceLineNo">1079</span>     * {@link org.apache.commons.math3.stat.descriptive.DescriptiveStatistics#DescriptiveStatistics()}.<a name="line.1079"></a>
-<span class="sourceLineNo">1080</span>     * It assumes that this is a zero sum set of costs.  It assumes that the worst case<a name="line.1080"></a>
-<span class="sourceLineNo">1081</span>     * possible is all of the elements in one region server and the rest having 0.<a name="line.1081"></a>
-<span class="sourceLineNo">1082</span>     *<a name="line.1082"></a>
-<span class="sourceLineNo">1083</span>     * @param stats the costs<a name="line.1083"></a>
-<span class="sourceLineNo">1084</span>     * @return a scaled set of costs.<a name="line.1084"></a>
-<span class="sourceLineNo">1085</span>     */<a name="line.1085"></a>
-<span class="sourceLineNo">1086</span>    protected double costFromArray(double[] stats) {<a name="line.1086"></a>
-<span class="sourceLineNo">1087</span>      double totalCost = 0;<a name="line.1087"></a>
-<span class="sourceLineNo">1088</span>      double total = getSum(stats);<a name="line.1088"></a>
-<span class="sourceLineNo">1089</span><a name="line.1089"></a>
-<span class="sourceLineNo">1090</span>      double count = stats.length;<a name="line.1090"></a>
-<span class="sourceLineNo">1091</span>      double mean = total/count;<a name="line.1091"></a>
-<span class="sourceLineNo">1092</span><a name="line.1092"></a>
-<span class="sourceLineNo">1093</span>      // Compute max as if all region servers had 0 and one had the sum of all costs.  This must be<a name="line.1093"></a>
-<span class="sourceLineNo">1094</span>      // a zero sum cost for this to make sense.<a name="line.1094"></a>
-<span class="sourceLineNo">1095</span>      double max = ((count - 1) * mean) + (total - mean);<a name="line.1095"></a>
-<span class="sourceLineNo">1096</span><a name="line.1096"></a>
-<span class="sourceLineNo">1097</span>      // It's possible that there aren't enough regions to go around<a name="line.1097"></a>
-<span class="sourceLineNo">1098</span>      double min;<a name="line.1098"></a>
-<span class="sourceLineNo">1099</span>      if (count &gt; total) {<a name="line.1099"></a>
-<span class="sourceLineNo">1100</span>        min = ((count - total) * mean) + ((1 - mean) * total);<a name="line.1100"></a>
-<span class="sourceLineNo">1101</span>      } else {<a name="line.1101"></a>
-<span class="sourceLineNo">1102</span>        // Some will have 1 more than everything else.<a name="line.1102"></a>
-<span class="sourceLineNo">1103</span>        int numHigh = (int) (total - (Math.floor(mean) * count));<a name="line.1103"></a>
-<span class="sourceLineNo">1104</span>        int numLow = (int) (count - numHigh);<a name="line.1104"></a>
-<span class="sourceLineNo">1105</span><a name="line.1105"></a>
-<span class="sourceLineNo">1106</span>        min = (numHigh * (Math.ceil(mean) - mean)) + (numLow * (mean - Math.floor(mean)));<a name="line.1106"></a>
+<span class="sourceLineNo">1076</span>    protected abstract double cost();<a name="line.1076"></a>
+<span class="sourceLineNo">1077</span><a name="line.1077"></a>
+<span class="sourceLineNo">1078</span>    @SuppressWarnings("checkstyle:linelength")<a name="line.1078"></a>
+<span class="sourceLineNo">1079</span>    /**<a name="line.1079"></a>
+<span class="sourceLineNo">1080</span>     * Function to compute a scaled cost using<a name="line.1080"></a>
+<span class="sourceLineNo">1081</span>     * {@link org.apache.commons.math3.stat.descriptive.DescriptiveStatistics#DescriptiveStatistics()}.<a name="line.1081"></a>
+<span class="sourceLineNo">1082</span>     * It assumes that this is a zero sum set of costs.  It assumes that the worst case<a name="line.1082"></a>
+<span class="sourceLineNo">1083</span>     * possible is all of the elements in one region server and the rest having 0.<a name="line.1083"></a>
+<span class="sourceLineNo">1084</span>     *<a name="line.1084"></a>
+<span class="sourceLineNo">1085</span>     * @param stats the costs<a name="line.1085"></a>
+<span class="sourceLineNo">1086</span>     * @return a scaled set of costs.<a name="line.1086"></a>
+<span class="sourceLineNo">1087</span>     */<a name="line.1087"></a>
+<span class="sourceLineNo">1088</span>    protected double costFromArray(double[] stats) {<a name="line.1088"></a>
+<span class="sourceLineNo">1089</span>      double totalCost = 0;<a name="line.1089"></a>
+<span class="sourceLineNo">1090</span>      double total = getSum(stats);<a name="line.1090"></a>
+<span class="sourceLineNo">1091</span><a name="line.1091"></a>
+<span class="sourceLineNo">1092</span>      double count = stats.length;<a name="line.1092"></a>
+<span class="sourceLineNo">1093</span>      double mean = total/count;<a name="line.1093"></a>
+<span class="sourceLineNo">1094</span><a name="line.1094"></a>
+<span class="sourceLineNo">1095</span>      // Compute max as if all region servers had 0 and one had the sum of all costs.  This must be<a name="line.1095"></a>
+<span class="sourceLineNo">1096</span>      // a zero sum cost for this to make sense.<a name="line.1096"></a>
+<span class="sourceLineNo">1097</span>      double max = ((count - 1) * mean) + (total - mean);<a name="line.1097"></a>
+<span class="sourceLineNo">1098</span><a name="line.1098"></a>
+<span class="sourceLineNo">1099</span>      // It's possible that there aren't enough regions to go around<a name="line.1099"></a>
+<span class="sourceLineNo">1100</span>      double min;<a name="line.1100"></a>
+<span class="sourceLineNo">1101</span>      if (count &gt; total) {<a name="line.1101"></a>
+<span class="sourceLineNo">1102</span>        min = ((count - total) * mean) + ((1 - mean) * total);<a name="line.1102"></a>
+<span class="sourceLineNo">1103</span>      } else {<a name="line.1103"></a>
+<span class="sourceLineNo">1104</span>        // Some will have 1 more than everything else.<a name="line.1104"></a>
+<span class="sourceLineNo">1105</span>        int numHigh = (int) (total - (Math.floor(mean) * count));<a name="line.1105"></a>
+<span class="sourceLineNo">1106</span>        int numLow = (int) (count - numHigh);<a name="line.1106"></a>
 <span class="sourceLineNo">1107</span><a name="line.1107"></a>
-<span class="sourceLineNo">1108</span>      }<a name="line.1108"></a>
-<span class="sourceLineNo">1109</span>      min = Math.max(0, min);<a name="line.1109"></a>
-<span class="sourceLineNo">1110</span>      for (int i=0; i&lt;stats.length; i++) {<a name="line.1110"></a>
-<span class="sourceLineNo">1111</span>        double n = stats[i];<a name="line.1111"></a>
-<span class="sourceLineNo">1112</span>        double diff = Math.abs(mean - n);<a name="line.1112"></a>
-<span class="sourceLineNo">1113</span>        totalCost += diff;<a name="line.1113"></a>
-<span class="sourceLineNo">1114</span>      }<a name="line.1114"></a>
-<span class="sourceLineNo">1115</span><a name="line.1115"></a>
-<span class="sourceLineNo">1116</span>      double scaled =  scale(min, max, totalCost);<a name="line.1116"></a>
-<span class="sourceLineNo">1117</span>      return scaled;<a name="line.1117"></a>
-<span class="sourceLineNo">1118</span>    }<a name="line.1118"></a>
-<span class="sourceLineNo">1119</span><a name="line.1119"></a>
-<span class="sourceLineNo">1120</span>    private double getSum(double[] stats) {<a name="line.1120"></a>
-<span class="sourceLineNo">1121</span>      double total = 0;<a name="line.1121"></a>
-<span class="sourceLineNo">1122</span>      for(double s:stats) {<a name="line.1122"></a>
-<span class="sourceLineNo">1123</span>        total += s;<a name="line.1123"></a>
-<span class="sourceLineNo">1124</span>      }<a name="line.1124"></a>
-<span class="sourceLineNo">1125</span>      return total;<a name="line.1125"></a>
-<span class="sourceLineNo">1126</span>    }<a name="line.1126"></a>
-<span class="sourceLineNo">1127</span><a name="line.1127"></a>
-<span class="sourceLineNo">1128</span>    /**<a name="line.1128"></a>
-<span class="sourceLineNo">1129</span>     * Scale the value between 0 and 1.<a name="line.1129"></a>
-<span class="sourceLineNo">1130</span>     *<a name="line.1130"></a>
-<span class="sourceLineNo">1131</span>     * @param min   Min value<a name="line.1131"></a>
-<span class="sourceLineNo">1132</span>     * @param max   The Max value<a name="line.1132"></a>
-<span class="sourceLineNo">1133</span>     * @param value The value to be scaled.<a name="line.1133"></a>
-<span class="sourceLineNo">1134</span>     * @return The scaled value.<a name="line.1134"></a>
-<span class="sourceLineNo">1135</span>     */<a name="line.1135"></a>
-<span class="sourceLineNo">1136</span>    protected double scale(double min, double max, double value) {<a name="line.1136"></a>
-<span class="sourceLineNo">1137</span>      if (max &lt;= min || value &lt;= min) {<a name="line.1137"></a>
-<span class="sourceLineNo">1138</span>        return 0;<a name="line.1138"></a>
-<span class="sourceLineNo">1139</span>      }<a name="line.1139"></a>
-<span class="sourceLineNo">1140</span>      if ((max - min) == 0) return 0;<a name="line.1140"></a>
-<span class="sourceLineNo">1141</span><a name="line.1141"></a>
-<span class="sourceLineNo">1142</span>      return Math.max(0d, Math.min(1d, (value - min) / (max - min)));<a name="line.1142"></a>
-<span class="sourceLineNo">1143</span>    }<a name="line.1143"></a>
-<span class="sourceLineNo">1144</span>  }<a name="line.1144"></a>
-<span class="sourceLineNo">1145</span><a name="line.1145"></a>
-<span class="sourceLineNo">1146</span>  /**<a name="line.1146"></a>
-<span class="sourceLineNo">1147</span>   * Given the starting state of the regions and a potential ending state<a name="line.1147"></a>
-<span class="sourceLineNo">1148</span>   * compute cost based upon the number of regions that have moved.<a name="line.1148"></a>
-<span class="sourceLineNo">1149</span>   */<a name="line.1149"></a>
-<span class="sourceLineNo">1150</span>  static class MoveCostFunction extends CostFunction {<a name="line.1150"></a>
-<span class="sourceLineNo">1151</span>    private static final String MOVE_COST_KEY = "hbase.master.balancer.stochastic.moveCost";<a name="line.1151"></a>
-<span class="sourceLineNo">1152</span>    private static final String MAX_MOVES_PERCENT_KEY =<a name="line.1152"></a>
-<span class="sourceLineNo">1153</span>        "hbase.master.balancer.stochastic.maxMovePercent";<a name="line.1153"></a>
-<span class="sourceLineNo">1154</span>    private static final float DEFAULT_MOVE_COST = 7;<a name="line.1154"></a>
-<span class="sourceLineNo">1155</span>    private static final int DEFAULT_MAX_MOVES = 600;<a name="line.1155"></a>
-<span class="sourceLineNo">1156</span>    private static final float DEFAULT_MAX_MOVE_PERCENT = 0.25f;<a name="line.1156"></a>
-<span class="sourceLineNo">1157</span><a name="line.1157"></a>
-<span class="sourceLineNo">1158</span>    private final float maxMovesPercent;<a name="line.1158"></a>
+<span class="sourceLineNo">1108</span>        min = (numHigh * (Math.ceil(mean) - mean)) + (numLow * (mean - Math.floor(mean)));<a name="line.1108"></a>
+<span class="sourceLineNo">1109</span><a name="line.1109"></a>
+<span class="sourceLineNo">1110</span>      }<a name="line.1110"></a>
+<span class="sourceLineNo">1111</span>      min = Math.max(0, min);<a name="line.1111"></a>
+<span class="sourceLineNo">1112</span>      for (int i=0; i&lt;stats.length; i++) {<a name="line.1112"></a>
+<span class="sourceLineNo">1113</span>        double n = stats[i];<a name="line.1113"></a>
+<span class="sourceLineNo">1114</span>        double diff = Math.abs(mean - n);<a name="line.1114"></a>
+<span class="sourceLineNo">1115</span>        totalCost += diff;<a name="line.1115"></a>
+<span class="sourceLineNo">1116</span>      }<a name="line.1116"></a>
+<span class="sourceLineNo">1117</span><a name="line.1117"></a>
+<span class="sourceLineNo">1118</span>      double scaled =  scale(min, max, totalCost);<a name="line.1118"></a>
+<span class="sourceLineNo">1119</span>      return scaled;<a name="line.1119"></a>
+<span class="sourceLineNo">1120</span>    }<a name="line.1120"></a>
+<span class="sourceLineNo">1121</span><a name="line.1121"></a>
+<span class="sourceLineNo">1122</span>    private double getSum(double[] stats) {<a name="line.1122"></a>
+<span class="sourceLineNo">1123</span>      double total = 0;<a name="line.1123"></a>
+<span class="sourceLineNo">1124</span>      for(double s:stats) {<a name="line.1124"></a>
+<span class="sourceLineNo">1125</span>        total += s;<a name="line.1125"></a>
+<span class="sourceLineNo">1126</span>      }<a name="line.1126"></a>
+<span class="sourceLineNo">1127</span>      return total;<a name="line.1127"></a>
+<span class="sourceLineNo">1128</span>    }<a name="line.1128"></a>
+<span class="sourceLineNo">1129</span><a name="line.1129"></a>
+<span class="sourceLineNo">1130</span>    /**<a name="line.1130"></a>
+<span class="sourceLineNo">1131</span>     * Scale the value between 0 and 1.<a name="line.1131"></a>
+<span class="sourceLineNo">1132</span>     *<a name="line.1132"></a>
+<span class="sourceLineNo">1133</span>     * @param min   Min value<a name="line.1133"></a>
+<span class="sourceLineNo">1134</span>     * @param max   The Max value<a name="line.1134"></a>
+<span class="sourceLineNo">1135</span>     * @param value The value to be scaled.<a name="line.1135"></a>
+<span class="sourceLineNo">1136</span>     * @return The scaled value.<a name="line.1136"></a>
+<span class="sourceLineNo">1137</span>     */<a name="line.1137"></a>
+<span class="sourceLineNo">1138</span>    protected double scale(double min, double max, double value) {<a name="line.1138"></a>
+<span class="sourceLineNo">1139</span>      if (max &lt;= min || value &lt;= min) {<a name="line.1139"></a>
+<span class="sourceLineNo">1140</span>        return 0;<a name="line.1140"></a>
+<span class="sourceLineNo">1141</span>      }<a name="line.1141"></a>
+<span class="sourceLineNo">1142</span>      if ((max - min) == 0) return 0;<a name="line.1142"></a>
+<span class="sourceLineNo">1143</span><a name="line.1143"></a>
+<span class="sourceLineNo">1144</span>      return Math.max(0d, Math.min(1d, (value - min) / (max - min)));<a name="line.1144"></a>
+<span class="sourceLineNo">1145</span>    }<a name="line.1145"></a>
+<span class="sourceLineNo">1146</span>  }<a name="line.1146"></a>
+<span class="sourceLineNo">1147</span><a name="line.1147"></a>
+<span class="sourceLineNo">1148</span>  /**<a name="line.1148"></a>
+<span class="sourceLineNo">1149</span>   * Given the starting state of the regions and a potential ending state<a name="line.1149"></a>
+<span class="sourceLineNo">1150</span>   * compute cost based upon the number of regions that have moved.<a name="line.1150"></a>
+<span class="sourceLineNo">1151</span>   */<a name="line.1151"></a>
+<span class="sourceLineNo">1152</span>  static class MoveCostFunction extends CostFunction {<a name="line.1152"></a>
+<span class="sourceLineNo">1153</span>    private static final String MOVE_COST_KEY = "hbase.master.balancer.stochastic.moveCost";<a name="line.1153"></a>
+<span class="sourceLineNo">1154</span>    private static final String MAX_MOVES_PERCENT_KEY =<a name="line.1154"></a>
+<span class="sourceLineNo">1155</span>        "hbase.master.balancer.stochastic.maxMovePercent";<a name="line.1155"></a>
+<span class="sourceLineNo">1156</span>    private static final float DEFAULT_MOVE_COST = 7;<a name="line.1156"></a>
+<span class="sourceLineNo">1157</span>    private static final int DEFAULT_MAX_MOVES = 600;<a name="line.1157"></a>
+<span class="sourceLineNo">1158</span>    private static final float DEFAULT_MAX_MOVE_PERCENT = 0.25f;<a name="line.1158"></a>
 <span class="sourceLineNo">1159</span><a name="line.1159"></a>
-<span class="sourceLineNo">1160</span>    MoveCostFunction(Configuration conf) {<a name="line.1160"></a>
-<span class="sourceLineNo">1161</span>      super(conf);<a name="line.1161"></a>
-<span class="sourceLineNo">1162</span><a name="line.1162"></a>
-<span class="sourceLineNo">1163</span>      // Move cost multiplier should be the same cost or higher than the rest of the costs to ensure<a name="line.1163"></a>
-<span class="sourceLineNo">1164</span>      // that large benefits are need to overcome the cost of a move.<a name="line.1164"></a>
-<span class="sourceLineNo">1165</span>      this.setMultiplier(conf.getFloat(MOVE_COST_KEY, DEFAULT_MOVE_COST));<a name="line.1165"></a>
-<span class="sourceLineNo">1166</span>      // What percent of the number of regions a single run of the balancer can move.<a name="line.1166"></a>
-<span class="sourceLineNo">1167</span>      maxMovesPercent = conf.getFloat(MAX_MOVES_PERCENT_KEY, DEFAULT_MAX_MOVE_PERCENT);<a name="line.1167"></a>
-<span class="sourceLineNo">1168</span>    }<a name="line.1168"></a>
-<span class="sourceLineNo">1169</span><a name="line.1169"></a>
-<span class="sourceLineNo">1170</span>    @Override<a name="line.1170"></a>
-<span class="sourceLineNo">1171</span>    protected double cost() {<a name="line.1171"></a>
-<span class="sourceLineNo">1172</span>      // Try and size the max number of Moves, but always be prepared to move some.<a name="line.1172"></a>
-<span class="sourceLineNo">1173</span>      int maxMoves = Math.max((int) (cluster.numRegions * maxMovesPercent),<a name="line.1173"></a>
-<span class="sourceLineNo">1174</span>          DEFAULT_MAX_MOVES);<a name="line.1174"></a>
-<span class="sourceLineNo">1175</span><a name="line.1175"></a>
-<span class="sourceLineNo">1176</span>      double moveCost = cluster.numMovedRegions;<a name="line.1176"></a>
+<span class="sourceLineNo">1160</span>    private final float maxMovesPercent;<a name="line.1160"></a>
+<span class="sourceLineNo">1161</span><a name="line.1161"></a>
+<span class="sourceLineNo">1162</span>    MoveCostFunction(Configuration conf) {<a name="line.1162"></a>
+<span class="sourceLineNo">1163</span>      super(conf);<a name="line.1163"></a>
+<span class="sourceLineNo">1164</span><a name="line.1164"></a>
+<span class="sourceLineNo">1165</span>      // Move cost multiplier should be the same cost or higher than the rest of the costs to ensure<a name="line.1165"></a>
+<span class="sourceLineNo">1166</span>      // that large benefits are need to overcome the cost of a move.<a name="line.1166"></a>
+<span class="sourceLineNo">1167</span>      this.setMultiplier(conf.getFloat(MOVE_COST_KEY, DEFAULT_MOVE_COST));<a name="line.1167"></a>
+<span class="sourceLineNo">1168</span>      // What percent of the number of regions a single run of the balancer can move.<a name="line.1168"></a>
+<span class="sourceLineNo">1169</span>      maxMovesPercent = conf.getFloat(MAX_MOVES_PERCENT_KEY, DEFAULT_MAX_MOVE_PERCENT);<a name="line.1169"></a>
+<span class="sourceLineNo">1170</span>    }<a name="line.1170"></a>
+<span class="sourceLineNo">1171</span><a name="line.1171"></a>
+<span class="sourceLineNo">1172</span>    @Override<a name="line.1172"></a>
+<span class="sourceLineNo">1173</span>    protected double cost() {<a name="line.1173"></a>
+<span class="sourceLineNo">1174</span>      // Try and size the max number of Moves, but always be prepared to move some.<a name="line.1174"></a>
+<span class="sourceLineNo">1175</span>      int maxMoves = Math.max((int) (cluster.numRegions * maxMovesPercent),<a name="line.1175"></a>
+<span class="sourceLineNo">1176</span>          DEFAULT_MAX_MOVES);<a name="line.1176"></a>
 <span class="sourceLineNo">1177</span><a name="line.1177"></a>
-<span class="sourceLineNo">1178</span>      // Don't let this single balance move more than the max moves.<a name="line.1178"></a>
-<span class="sourceLineNo">1179</span>      // This allows better scaling to accurately represent the actual cost of a move.<a name="line.1179"></a>
-<span class="sourceLineNo">1180</span>      if (moveCost &gt; maxMoves) {<a name="line.1180"></a>
-<span class="sourceLineNo">1181</span>        return 1000000;   // return a number much greater than any of the other cost<a name="line.1181"></a>
-<span class="sourceLineNo">1182</span>      }<a name="line.1182"></a>
-<span class="sourceLineNo">1183</span><a name="line.1183"></a>
-<span class="sourceLineNo">1184</span>      return scale(0, Math.min(cluster.numRegions, maxMoves), moveCost);<a name="line.1184"></a>
-<span class="sourceLineNo">1185</span>    }<a name="line.1185"></a>
-<span class="sourceLineNo">1186</span>  }<a name="line.1186"></a>
-<span class="sourceLineNo">1187</span><a name="line.1187"></a>
-<span class="sourceLineNo">1188</span>  /**<a name="line.1188"></a>
-<span class="sourceLineNo">1189</span>   * Compute the cost of a potential cluster state from skew in number of<a name="line.1189"></a>
-<span class="sourceLineNo">1190</span>   * regions on a cluster.<a name="line.1190"></a>
-<span class="sourceLineNo">1191</span>   */<a name="line.1191"></a>
-<span class="sourceLineNo">1192</span>  static class RegionCountSkewCostFunction extends CostFunction {<a name="line.1192"></a>
-<span class="sourceLineNo">1193</span>    private static final String REGION_COUNT_SKEW_COST_KEY =<a name="line.1193"></a>
-<span class="sourceLineNo">1194</span>        "hbase.master.balancer.stochastic.regionCountCost";<a name="line.1194"></a>
-<span class="sourceLineNo">1195</span>    private static final float DEFAULT_REGION_COUNT_SKEW_COST = 500;<a name="line.1195"></a>
-<span class="sourceLineNo">1196</span><a name="line.1196"></a>
-<span class="sourceLineNo">1197</span>    private double[] stats = null;<a name="line.1197"></a>
+<span class="sourceLineNo">1178</span>      double moveCost = cluster.numMovedRegions;<a name="line.1178"></a>
+<span class="sourceLineNo">1179</span><a name="line.1179"></a>
+<span class="sourceLineNo">1180</span>      // Don't let this single balance move more than the max moves.<a name="line.1180"></a>
+<span class="sourceLineNo">1181</span>      // This allows better scaling to accurately represent the actual cost of a move.<a name="line.1181"></a>
+<span class="sourceLineNo">1182</span>      if (moveCost &gt; maxMoves) {<a name="line.1182"></a>
+<span class="sourceLineNo">1183</span>        return 1000000;   // return a number much greater than any of the other cost<a name="line.1183"></a>
+<span class="sourceLineNo">1184</span>      }<a name="line.1184"></a>
+<span class="sourceLineNo">1185</span><a name="line.1185"></a>
+<span class="sourceLineNo">1186</span>      return scale(0, Math.min(cluster.numRegions, maxMoves), moveCost);<a name="line.1186"></a>
+<span class="sourceLineNo">1187</span>    }<a name="line.1187"></a>
+<span class="sourceLineNo">1188</span>  }<a name="line.1188"></a>
+<span class="sourceLineNo">1189</span><a name="line.1189"></a>
+<span class="sourceLineNo">1190</span>  /**<a name="line.1190"></a>
+<span class="sourceLineNo">1191</span>   * Compute the cost of a potential cluster state from skew in number of<a name="line.1191"></a>
+<span class="sourceLineNo">1192</span>   * regions on a cluster.<a name="line.1192"></a>
+<span class="sourceLineNo">1193</span>   */<a name="line.1193"></a>
+<span class="sourceLineNo">1194</span>  static class RegionCountSkewCostFunction extends CostFunction {<a name="line.1194"></a>
+<span class="sourceLineNo">1195</span>    private static final String REGION_COUNT_SKEW_COST_KEY =<a name="line.1195"></a>
+<span class="sourceLineNo">1196</span>        "hbase.master.balancer.stochastic.regionCountCost";<a name="line.1196"></a>
+<span class="sourceLineNo">1197</span>    private static final float DEFAULT_REGION_COUNT_SKEW_COST = 500;<a name="line.1197"></a>
 <span class="sourceLineNo">1198</span><a name="line.1198"></a>
-<span class="sourceLineNo">1199</span>    RegionCountSkewCostFunction(Configuration conf) {<a name="line.1199"></a>
-<span class="sourceLineNo">1200</span>      super(conf);<a name="line.1200"></a>
-<span class="sourceLineNo">1201</span>      // Load multiplier should be the greatest as it is the most general way to balance data.<a name="line.1201"></a>
-<span class="sourceLineNo">1202</span>      this.setMultiplier(conf.getFloat(REGION_COUNT_SKEW_COST_KEY, DEFAULT_REGION_COUNT_SKEW_COST));<a name="line.1202"></a>
-<span class="sourceLineNo">1203</span>    }<a name="line.1203"></a>
-<span class="sourceLineNo">1204</span><a name="line.1204"></a>
-<span class="sourceLineNo">1205</span>    @Override<a name="line.1205"></a>
-<span class="sourceLineNo">1206</span>    protected double cost() {<a name="line.1206"></a>
-<span class="sourceLineNo">1207</span>      if (stats == null || stats.length != cluster.numServers) {<a name="line.1207"></a>
-<span class="sourceLineNo">1208</span>        stats = new double[cluster.numServers];<a name="line.1208"></a>
-<span class="sourceLineNo">1209</span>      }<a name="line.1209"></a>
-<span class="sourceLineNo">1210</span><a name="line.1210"></a>
-<span class="sourceLineNo">1211</span>      for (int i =0; i &lt; cluster.numServers; i++) {<a name="line.1211"></a>
-<span class="sourceLineNo">1212</span>        stats[i] = cluster.regionsPerServer[i].length;<a name="line.1212"></a>
-<span class="sourceLineNo">1213</span>      }<a name="line.1213"></a>
-<span class="sourceLineNo">1214</span><a name="line.1214"></a>
-<span class="sourceLineNo">1215</span>      return costFromArray(stats);<a name="line.1215"></a>
-<span class="sourceLineNo">1216</span>    }<a name="line.1216"></a>
-<span class="sourceLineNo">1217</span>  }<a name="line.1217"></a>
-<span class="sourceLineNo">1218</span><a name="line.1218"></a>
-<span class="sourceLineNo">1219</span>  /**<a name="line.1219"></a>
-<span class="sourceLineNo">1220</span>   * Compute the cost of a potential cluster state from skew in number of<a name="line.1220"></a>
-<span class="sourceLineNo">1221</span>   * primary regions on a cluster.<a name="line.1221"></a>
-<span class="sourceLineNo">1222</span>   */<a name="line.1222"></a>
-<span class="sourceLineNo">1223</span>  static class PrimaryRegionCountSkewCostFunction extends CostFunction {<a name="line.1223"></a>
-<span class="sourceLineNo">1224</span>    private static final String PRIMARY_REGION_COUNT_SKEW_COST_KEY =<a name="line.1224"></a>
-<span class="sourceLineNo">1225</span>        "hbase.master.balancer.stochastic.primaryRegionCountCost";<a name="line.1225"></a>
-<span class="sourceLineNo">1226</span>    private static final float DEFAULT_PRIMARY_REGION_COUNT_SKEW_COST = 500;<a name="line.1226"></a>
-<span class="sourceLineNo">1227</span><a name="line.1227"></a>
-<span class="sourceLineNo">1228</span>    private double[] stats = null;<a name="line.1228"></a>
+<span class="sourceLineNo">1199</span>    private double[] stats = null;<a name="line.1199"></a>
+<span class="sourceLineNo">1200</span><a name="line.1200"></a>
+<span class="sourceLineNo">1201</span>    RegionCountSkewCostFunction(Configuration conf) {<a name="line.1201"></a>
+<span class="sourceLineNo">1202</span>      super(conf);<a name="line.1202"></a>
+<span class="sourceLineNo">1203</span>      // Load multiplier should be the greatest as it is the most general way to balance data.<a name="line.1203"></a>
+<span class="sourceLineNo">1204</span>      this.setMultiplier(conf.getFloat(REGION_COUNT_SKEW_COST_KEY, DEFAULT_REGION_COUNT_SKEW_COST));<a name="line.1204"></a>
+<span class="sourceLineNo">1205</span>    }<a name="line.1205"></a>
+<span class="sourceLineNo">1206</span><a name="line.1206"></a>
+<span class="sourceLineNo">1207</span>    @Override<a name="line.1207"></a>
+<span class="sourceLineNo">1208</span>    protected double cost() {<a name="line.1208"></a>
+<span class="sourceLineNo">1209</span>      if (stats == null || stats.length != cluster.numServers) {<a name="line.1209"></a>
+<span class="sourceLineNo">1210</span>        stats = new double[cluster.numServers];<a name="line.1210"></a>
+<span class="sourceLineNo">1211</span>      }<a name="line.1211"></a>
+<span class="sourceLineNo">1212</span><a name="line.1212"></a>
+<span class="sourceLineNo">1213</span>      for (int i =0; i &lt; cluster.numServers; i++) {<a name="line.1213"></a>
+<span class="sourceLineNo">1214</span>        stats[i] = cluster.regionsPerServer[i].length;<a name="line.1214"></a>
+<span class="sourceLineNo">1215</span>      }<a name="line.1215"></a>
+<span class="sourceLineNo">1216</span><a name="line.1216"></a>
+<span class="sourceLineNo">1217</span>      return costFromArray(stats);<a name="line.1217"></a>
+<span class="sourceLineNo">1218</span>    }<a name="line.1218"></a>
+<span class="sourceLineNo">1219</span>  }<a name="line.1219"></a>
+<span class="sourceLineNo">1220</span><a name="line.1220"></a>
+<span class="sourceLineNo">1221</span>  /**<a name="line.1221"></a>
+<span class="sourceLineNo">1222</span>   * Compute the cost of a potential cluster state from skew in number of<a name="line.1222"></a>
+<span class="sourceLineNo">1223</span>   * primary regions on a cluster.<a name="line.1223"></a>
+<span class="sourceLineNo">1224</span>   */<a name="line.1224"></a>
+<span class="sourceLineNo">1225</span>  static class PrimaryRegionCountSkewCostFunction extends CostFunction {<a name="line.1225"></a>
+<span class="sourceLineNo">1226</span>    private static final String PRIMARY_REGION_COUNT_SKEW_COST_KEY =<a name="line.1226"></a>
+<span class="sourceLineNo">1227</span>        "hbase.master.balancer.stochastic.primaryRegionCountCost";<a name="line.1227"></a>
+<span class="sourceLineNo">1228</span>    private static final float DEFAULT_PRIMARY_REGION_COUNT_SKEW_COST = 500;<a name="line.1228"></a>
 <span class="sourceLineNo">1229</span><a name="line.1229"></a>
-<span class="sourceLineNo">1230</span>    PrimaryRegionCountSkewCostFunction(Configuration conf) {<a name="line.1230"></a>
-<span class="sourceLineNo">1231</span>      super(conf);<a name="line.1231"></a>
-<span class="sourceLineNo">1232</span>      // Load multiplier should be the greatest as primary regions serve majority of reads/writes.<a name="line.1232"></a>
-<span class="sourceLineNo">1233</span>      this.setMultiplier(conf.getFloat(PRIMARY_REGION_COUNT_SKEW_COST_KEY,<a name="line.1233"></a>
-<span class="sourceLineNo">1234</span>        DEFAULT_PRIMARY_REGION_COUNT_SKEW_COST));<a name="line.1234"></a>
-<span class="sourceLineNo">1235</span>    }<a name="line.1235"></a>
-<span class="sourceLineNo">1236</span><a name="line.1236"></a>
-<span class="sourceLineNo">1237</span>    @Override<a name="line.1237"></a>
-<span class="sourceLineNo">1238</span>    protected double cost() {<a name="line.1238"></a>
-<span class="sourceLineNo">1239</span>      if (!cluster.hasRegionReplicas) {<a name="line.1239"></a>
-<span class="sourceLineNo">1240</span>        return 0;<a name="line.1240"></a>
-<span class="sourceLineNo">1241</span>      }<a name="line.1241"></a>
-<span class="sourceLineNo">1242</span>      if (stats == null || stats.length != cluster.numServers) {<a name="line.1242"></a>
-<span class="sourceLineNo">1243</span>        stats = new double[cluster.numServers];<a name="line.1243"></a>
-<span class="sourceLineNo">1244</span>      }<a name="line.1244"></a>
-<span class="sourceLineNo">1245</span><a name="line.1245"></a>
-<span class="sourceLineNo">1246</span>      for (int i = 0; i &lt; cluster.numServers; i++) {<a name="line.1246"></a>
-<span class="sourceLineNo">1247</span>        stats[i] = 0;<a name="line.1247"></a>
-<span class="sourceLineNo">1248</span>        for (int regionIdx : cluster.regionsPerServer[i]) {<a name="line.1248"></a>
-<span class="sourceLineNo">1249</span>          if (regionIdx == cluster.regionIndexToPrimaryIndex[regionIdx]) {<a name="line.1249"></a>
-<span class="sourceLineNo">1250</span>            stats[i]++;<a name="line.1250"></a>
-<span class="sourceLineNo">1251</span>          }<a name="line.1251"></a>
-<span class="sourceLineNo">1252</span>        }<a name="line.1252"></a>
-<span class="sourceLineNo">1253</span>      }<a name="line.1253"></a>
-<span class="sourceLineNo">1254</span><a name="line.1254"></a>
-<span class="sourceLineNo">1255</span>      return costFromArray(stats);<a name="line.1255"></a>
-<span class="sourceLineNo">1256</span>    }<a name="line.1256"></a>
-<span class="sourceLineNo">1257</span>  }<a name="line.1257"></a>
-<span class="sourceLineNo">1258</span><a name="line.1258"></a>
-<span class="sourceLineNo">1259</span>  /**<a name="line.1259"></a>
-<span class="sourceLineNo">1260</span>   * Compute the cost of a potential cluster configuration based upon how evenly<a name="line.1260"></a>
-<span class="sourceLineNo">1261</span>   * distributed tables are.<a name="line.1261"></a>
-<span class="sourceLineNo">1262</span>   */<a name="line.1262"></a>
-<span class="sourceLineNo">1263</span>  static class TableSkewCostFunction extends CostFunction {<a name="line.1263"></a>
-<span class="sourceLineNo">1264</span><a name="line.1264"></a>
-<span class="sourceLineNo">1265</span>    private static final String TABLE_SKEW_COST_KEY =<a name="line.1265"></a>
-<span class="sourceLineNo">1266</span>        "hbase.master.balancer.stochastic.tableSkewCost";<a name="line.1266"></a>
-<span class="sourceLineNo">1267</span>    private static final float DEFAULT_TABLE_SKEW_COST = 35;<a name="line.1267"></a>
-<span class="sourceLineNo">1268</span><a name="line.1268"></a>
-<span class="sourceLineNo">1269</span>    TableSkewCostFunction(Configuration conf) {<a name="line.1269"></a>
-<span class="sourceLineNo">1270</span>      super(conf);<a name="line.1270"></a>
-<span class="sourceLineNo">1271</span>      this.setMultiplier(conf.getFloat(TABLE_SKEW_COST_KEY, DEFAULT_TABLE_SKEW_COST));<a name="line.1271"></a>
-<span class="sourceLineNo">1272</span>    }<a name="line.1272"></a>
-<span class="sourceLineNo">1273</span><a name="line.1273"></a>
-<span class="sourceLineNo">1274</span>    @Override<a name="line.1274"></a>
-<span class="sourceLineNo">1275</span>    protected double cost() {<a name="line.1275"></a>
-<span class="sourceLineNo">1276</span>      double max = cluster.numRegions;<a name="line.1276"></a>
-<span class="sourceLineNo">1277</span>      double min = ((double) cluster.numRegions) / cluster.numServers;<a name="line.1277"></a>
-<span class="sourceLineNo">1278</span>      double value = 0;<a name="line.1278"></a>
-<span class="sourceLineNo">1279</span><a name="line.1279"></a>
-<span class="sourceLineNo">1280</span>      for (int i = 0; i &lt; cluster.numMaxRegionsPerTable.length; i++) {<a name="line.1280"></a>
-<span class="sourceLineNo">1281</span>        value += cluster.numMaxRegionsPerTable[i];<a name="line.1281"></a>
-<span class="sourceLineNo">1282</span>      }<a name="line.1282"></a>
-<span class="sourceLineNo">1283</span><a name="line.1283"></a>
-<span class="sourceLineNo">1284</span>      return scale(min, max, value);<a name="line.1284"></a>
-<span class="sourceLineNo">1285</span>    }<a name="line.1285"></a>
-<span class="sourceLineNo">1286</span>  }<a name="line.1286"></a>
-<span class="sourceLineNo">1287</span><a name="line.1287"></a>
-<span class="sourceLineNo">1288</span>  /**<a name="line.1288"></a>
-<span class="sourceLineNo">1289</span>   * Compute a cost of a potential cluster configuration based upon where<a name="line.1289"></a>
-<span class="sourceLineNo">1290</span>   * {@link org.apache.hadoop.hbase.regionserver.HStoreFile}s are located.<a name="line.1290"></a>
-<span class="sourceLineNo">1291</span>   */<a name="line.1291"></a>
-<span class="sourceLineNo">1292</span>  static abstract class LocalityBasedCostFunction extends CostFunction {<a name="line.1292"></a>
-<span class="sourceLineNo">1293</span><a name="line.1293"></a>
-<span class="sourceLineNo">1294</span>    private final LocalityType type;<a name="line.1294"></a>
+<span class="sourceLineNo">1230</span>    private double[] stats = null;<a name="line.1230"></a>
+<span class="sourceLineNo">1231</span><a name="line.1231"></a>
+<span class="sourceLineNo">1232</span>    PrimaryRegionCountSkewCostFunction(Configuration conf) {<a name="line.1232"></a>
+<span class="sourceLineNo">1233</span>      super(conf);<a name="line.1233"></a>
+<span class="sourceLineNo">1234</span>      // Load multiplier should be the greatest as primary regions serve majority of reads/writes.<a name="line.1234"></a>
+<span class="sourceLineNo">1235</span>      this.setMultiplier(conf.getFloat(PRIMARY_REGION_COUNT_SKEW_COST_KEY,<a name="line.1235"></a>
+<span class="sourceLineNo">1236</span>        DEFAULT_PRIMARY_REGION_COUNT_SKEW_COST));<a name="line.1236"></a>
+<span class="sourceLineNo">1237</span>    }<a name="line.1237"></a>
+<span class="sourceLineNo">1238</span><a name="line.1238"></a>
+<span class="sourceLineNo">1239</span>    @Override<a name="line.1239"></a>
+<span class="sourceLineNo">1240</span>    protected double cost() {<a name="line.1240"></a>
+<span class="sourceLineNo">1241</span>      if (!cluster.hasRegionReplicas) {<a name="line.1241"></a>
+<span class="sourceLineNo">1242</span>        return 0;<a name="line.1242"></a>
+<span class="sourceLineNo">1243</span>      }<a name="line.1243"></a>
+<span class="sourceLineNo">1244</span>      if (stats == null || stats.length != cluster.numServers) {<a name="line.1244"></a>
+<span class="sourceLineNo">1245</span>        stats = new double[cluster.numServers];<a name="line.1245"></a>
+<span class="sourceLineNo">1246</span>      }<a name="line.1246"></a>
+<span class="sourceLineNo">1247</span><a name="line.1247"></a>
+<span class="sourceLineNo">1248</span>      for (int i = 0; i &lt; cluster.numServers; i++) {<a name="line.1248"></a>
+<span class="sourceLineNo">1249</span>        stats[i] = 0;<a name="line.1249"></a>
+<span class="sourceLineNo">1250</span>        for (int regionIdx : cluster.regionsPerServer[i]) {<a name="line.1250"></a>
+<span class="sourceLineNo">1251</span>          if (regionIdx == cluster.regionIndexToPrimaryIndex[regionIdx]) {<a name="line.1251"></a>
+<span class="sourceLineNo">1252</span>            stats[i]++;<a name="line.1252"></a>
+<span class="sourceLineNo">1253</span>          }<a name="line.1253"></a>
+<span class="sourceLineNo">1254</span>        }<a name="line.1254"></a>
+<span class="sourceLineNo">1255</span>      }<a name="line.1255"></a>
+<span class="sourceLineNo">1256</span><a name="line.1256"></a>
+<span class="sourceLineNo">1257</span>      return costFromArray(stats);<a name="line.1257"></a>
+<span class="sourceLineNo">1258</span>    }<a name="line.1258"></a>
+<span class="sourceLineNo">1259</span>  }<a name="line.1259"></a>
+<span class="sourceLineNo">1260</span><a name="line.1260"></a>
+<span class="sourceLineNo">1261</span>  /**<a name="line.1261"></a>
+<span class="sourceLineNo">1262</span>   * Compute the cost of a potential cluster configuration based upon how evenly<a name="line.1262"></a>
+<span class="sourceLineNo">1263</span>   * distributed tables are.<a name="line.1263"></a>
+<span class="sourceLineNo">1264</span>   */<a name="line.1264"></a>
+<span class="sourceLineNo">1265</span>  static class TableSkewCostFunction extends CostFunction {<a name="line.1265"></a>
+<span class="sourceLineNo">1266</span><a name="line.1266"></a>
+<span class="sourceLineNo">1267</span>    private static final String TABLE_SKEW_COST_KEY =<a name="line.1267"></a>
+<span class="sourceLineNo">1268</span>        "hbase.master.balancer.stochastic.tableSkewCost";<a name="line.1268"></a>
+<span class="sourceLineNo">1269</span>    private static final float DEFAULT_TABLE_SKEW_COST = 35;<a name="line.1269"></a>
+<span class="sourceLineNo">1270</span><a name="line.1270"></a>
+<span class="sourceLineNo">1271</span>    TableSkewCostFunction(Configuration conf) {<a name="line.1271"></a>
+<span class="sourceLineNo">1272</span>      super(conf);<a name="line.1272"></a>
+<span class="sourceLineNo">1273</span>      this.setMultiplier(conf.getFloat(TABLE_SKEW_COST_KEY, DEFAULT_TABLE_SKEW_COST));<a name="line.1273"></a>
+<span class="sourceLineNo">1274</span>    }<a name="line.1274"></a>
+<span class="sourceLineNo">1275</span><a name="line.1275"></a>
+<span class="sourceLineNo">1276</span>    @Override<a name="line.1276"></a>
+<span class="sourceLineNo">1277</span>    protected double cost() {<a name="line.1277"></a>
+<span class="sourceLineNo">1278</span>      double max = cluster.numRegions;<a name="line.1278"></a>
+<span class="sourceLineNo">1279</span>      double min = ((double) cluster.numRegions) / cluster.numServers;<a name="line.1279"></a>
+<span class="sourceLineNo">1280</span>      double value = 0;<a name="line.1280"></a>
+<span class="sourceLineNo">1281</span><a name="line.1281"></a>
+<span class="sourceLineNo">1282</span>      for (int i = 0; i &lt; cluster.numMaxRegionsPerTable.length; i++) {<a name="line.1282"></a>
+<span class="sourceLineNo">1283</span>        value += cluster.numMaxRegionsPerTable[i];<a name="line.1283"></a>
+<span class="sourceLineNo">1284</span>      }<a name="line.1284"></a>
+<span class="sourceLineNo">1285</span><a name="line.1285"></a>
+<span class="sourceLineNo">1286</span>      return scale(min, max, value);<a name="line.1286"></a>
+<span class="sourceLineNo">1287</span>    }<a name="line.1287"></a>
+<span class="sourceLineNo">1288</span>  }<a name="line.1288"></a>
+<span class="sourceLineNo">1289</span><a name="line.1289"></a>
+<span class="sourceLineNo">1290</span>  /**<a name="line.1290"></a>
+<span class="sourceLineNo">1291</span>   * Compute a cost of a potential cluster configuration based upon where<a name="line.1291"></a>
+<span class="sourceLineNo">1292</span>   * {@link org.apache.hadoop.hbase.regionserver.HStoreFile}s are located.<a name="line.1292"></a>
+<span class="sourceLineNo">1293</span>   */<a name="line.1293"></a>
+<span class="sourceLineNo">1294</span>  static abstract class LocalityBasedCostFunction extends CostFunction {<a name="line.1294"></a>
 <span class="sourceLineNo">1295</span><a name="line.1295"></a>
-<span class="sourceLineNo">1296</span>    private double bestLocality; // best case locality across cluster weighted by local data size<a name="line.1296"></a>
-<span class="sourceLineNo">1297</span>    private double locality; // current locality across cluster weighted by local data size<a name="line.1297"></a>
-<span class="sourceLineNo">1298</span><a name="line.1298"></a>
-<span class="sourceLineNo">1299</span>    private MasterServices services;<a name="line.1299"></a>
+<span class="sourceLineNo">1296</span>    private final LocalityType type;<a name="line.1296"></a>
+<span class="sourceLineNo">1297</span><a name="line.1297"></a>
+<span class="sourceLineNo">1298</span>    private double bestLocality; // best case locality across cluster weighted by local data size<a name="line.1298"></a>
+<span class="sourceLineNo">1299</span>    private double locality; // current locality across cluster weighted by local data size<a name="line.1299"></a>
 <span class="sourceLineNo">1300</span><a name="line.1300"></a>
-<span class="sourceLineNo">1301</span>    LocalityBasedCostFunction(Configuration conf,<a name="line.1301"></a>
-<span class="sourceLineNo">1302</span>                              MasterServices srv,<a name="line.1302"></a>
-<span class="sourceLineNo">1303</span>                              LocalityType type,<a name="line.1303"></a>
-<span class="sourceLineNo">1304</span>                              String localityCostKey,<a name="line.1304"></a>
-<span class="sourceLineNo">1305</span>                              float defaultLocalityCost) {<a name="line.1305"></a>
-<span class="sourceLineNo">1306</span>      super(conf);<a name="line.1306"></a>
-<span class="sourceLineNo">1307</span>      this.type = type;<a name="line.1307"></a>
-<span class="sourceLineNo">1308</span>      this.setMultiplier(conf.getFloat(localityCostKey, defaultLocalityCost));<a name="line.1308"></a>
-<span class="sourceLineNo">1309</span>      this.services = srv;<a name="line.1309"></a>
-<span class="sourceLineNo">1310</span>      this.locality = 0.0;<a name="line.1310"></a>
-<span class="sourceLineNo">1311</span>      this.bestLocality = 0.0;<a name="line.1311"></a>
-<span class="sourceLineNo">1312</span>    }<a name="line.1312"></a>
-<span class="sourceLineNo">1313</span><a name="line.1313"></a>
-<span class="sourceLineNo">1314</span>    /**<a name="line.1314"></a>
-<span class="sourceLineNo">1315</span>     * Maps region to the current entity (server or rack) on which it is stored<a name="line.1315"></a>
-<span class="sourceLineNo">1316</span>     */<a name="line.1316"></a>
-<span class="sourceLineNo">1317</span>    abstract int regionIndexToEntityIndex(int region);<a name="line.1317"></a>
-<span class="sourceLineNo">1318</span><a name="line.1318"></a>
-<span class="sourceLineNo">1319</span>    public void setServices(MasterServices srvc) {<a name="line.1319"></a>
-<span class="sourceLineNo">1320</span>      this.services = srvc;<a name="line.1320"></a>
-<span class="sourceLineNo">1321</span>    }<a name="line.1321"></a>
-<span class="sourceLineNo">1322</span><a name="line.1322"></a>
-<span class="sourceLineNo">1323</span>    @Override<a name="line.1323"></a>
-<span class="sourceLineNo">1324</span>    void init(Cluster cluster) {<a name="line.1324"></a>
-<span class="sourceLineNo">1325</span>      super.init(cluster);<a name="line.1325"></a>
-<span class="sourceLineNo">1326</span>      locality = 0.0;<a name="line.1326"></a>
-<span class="sourceLineNo">1327</span>      bestLocality = 0.0;<a name="line.1327"></a>
-<span class="sourceLineNo">1328</span><a name="line.1328"></a>
-<span class="sourceLineNo">1329</span>      // If no master, no computation will work, so assume 0 cost<a name="line.1329"></a>
-<span class="sourceLineNo">1330</span>      if (this.services == null) {<a name="line.1330"></a>
-<span class="sourceLineNo">1331</span>        return;<a name="line.1331"></a>
-<span class="sourceLineNo">1332</span>      }<a name="line.1332"></a>
-<span class="sourceLineNo">1333</span><a name="line.1333"></a>
-<span class="sourceLineNo">1334</span>      for (int region = 0; region &lt; cluster.numRegions; region++) {<a name="line.1334"></a>
-<span class="sourceLineNo">1335</span>        locality += getWeightedLocality(region, regionIndexToEntityIndex(region));<a name="line.1335"></a>
-<span class="sourceLineNo">1336</span>        bestLocality += getWeightedLocality(region, getMostLocalEntityForRegion(region));<a name="line.1336"></a>
-<span class="sourceLineNo">1337</span>      }<a name="line.1337"></a>
-<span class="sourceLineNo">1338</span><a name="line.1338"></a>
-<span class="sourceLineNo">1339</span>      // We normalize locality to be a score between 0 and 1.0 representing how good it<a name="line.1339"></a>
-<span class="sourceLineNo">1340</span>      // is compared to how good it could be. If bestLocality is 0, assume locality is 100<a name="line.1340"></a>
-<span class="sourceLineNo">1341</span>      // (and the cost is 0)<a name="line.1341"></a>
-<span class="sourceLineNo">1342</span>      locality = bestLocality == 0 ? 1.0 : locality / bestLocality;<a name="line.1342"></a>
-<span class="sourceLineNo">1343</span>    }<a name="line.1343"></a>
-<span class="sourceLineNo">1344</span><a name="line.1344"></a>
-<span class="sourceLineNo">1345</span>    @Override<a name="line.1345"></a>
-<span class="sourceLineNo">1346</span>    protected void regionMoved(int region, int oldServer, int newServer) {<a name="line.1346"></a>
-<span class="sourceLineNo">1347</span>      int oldEntity = type == LocalityType.SERVER ? oldServer : cluster.serverIndexToRackIndex[oldServer];<a name="line.1347"></a>
-<span class="sourceLineNo">1348</span>      int newEntity = type == LocalityType.SERVER ? newServer : cluster.serverIndexToRackIndex[newServer];<a name="line.1348"></a>
-<span class="sourceLineNo">1349</span>      if (this.services == null) {<a name="line.1349"></a>
-<span class="sourceLineNo">1350</span>        return;<a name="line.1350"></a>
-<span class="sourceLineNo">1351</span>      }<a name="line.1351"></a>
-<span class="sourceLineNo">1352</span>      double localityDelta = getWeightedLocality(region, newEntity) - getWeightedLocality(region, oldEntity);<a name="line.1352"></a>
-<span class="sourceLineNo">1353</span>      double normalizedDelta = bestLocality == 0 ? 0.0 : localityDelta / bestLocality;<a name="line.1353"></a>
-<span class="sourceLineNo">1354</span>      locality += normalizedDelta;<a name="line.1354"></a>
-<span class="sourceLineNo">1355</span>    }<a name="line.1355"></a>
-<span class="sourceLineNo">1356</span><a name="line.1356"></a>
-<span class="sourceLineNo">1357</span>    @Override<a name="line.1357"></a>
-<span class="sourceLineNo">1358</span>    protected double cost() {<a name="line.1358"></a>
-<span class="sourceLineNo">1359</span>      return 1 - locality;<a name="line.1359"></a>
-<span class="sourceLineNo">1360</span>    }<a name="line.1360"></a>
-<span class="sourceLineNo">1361</span><a name="line.1361"></a>
-<span class="sourceLineNo">1362</span>    private int getMostLocalEntityForRegion(int region) {<a name="line.1362"></a>
-<span class="sourceLineNo">1363</span>      return cluster.getOrComputeRegionsToMostLocalEntities(type)[region];<a name="line.1363"></a>
-<span class="sourceLineNo">1364</span>    }<a name="line.1364"></a>
-<span class="sourceLineNo">1365</span><a name="line.1365"></a>
-<span class="sourceLineNo">1366</span>    private double getWeightedLocality(int region, int entity) {<a name="line.1366"></a>
-<span class="sourceLineNo">1367</span>      return cluster.getOrComputeWeightedLocality(region, entity, type);<a name="line.1367"></a>
-<span class="sourceLineNo">1368</span>    }<a name="line.1368"></a>
-<span class="sourceLineNo">1369</span><a name="line.1369"></a>
-<span class="sourceLineNo">1370</span>  }<a name="line.1370"></a>
+<span class="sourceLineNo">1301</span>    private MasterServices services;<a name="line.1301"></a>
+<span class="sourceLineNo">1302</span><a name="line.1302"></a>
+<span class="sourceLineNo">1303</span>    LocalityBasedCostFunction(Configuration conf,<a name="line.1303"></a>
+<span class="sourceLineNo">1304</span>                              MasterServices srv,<a name="line.1304"></a>
+<span class="sourceLineNo">1305</span>                              LocalityType type,<a name="line.1305"></a>
+<span class="sourceLineNo">1306</span>                              String localityCostKey,<a name="line.1306"></a>
+<span class="sourceLineNo">1307</span>                              float defaultLocalityCost) {<a name="line.1307"></a>
+<span class="sourceLineNo">1308</span>      super(conf);<a name="line.1308"></a>
+<span class="sourceLineNo">1309</span>      this.type = type;<a name="line.1309"></a>
+<span class="sourceLineNo">1310</span>      this.setMultiplier(conf.getFloat(localityCostKey, defaultLocalityCost));<a name="line.1310"></a>
+<span class="sourceLineNo">1311</span>      this.services = srv;<a name="line.1311"></a>
+<span class="sourceLineNo">1312</span>      this.locality = 0.0;<a name="line.1312"></a>
+<span class="sourceLineNo">1313</span>      this.bestLocality = 0.0;<a name="line.1313"></a>
+<span class="sourceLineNo">1314</span>    }<a name="line.1314"></a>
+<span class="sourceLineNo">1315</span><a name="line.1315"></a>
+<span class="sourceLineNo">1316</span>    /**<a name="line.1316"></a>
+<span class="sourceLineNo">1317</span>     * Maps region to the current entity (server or rack) on which it is stored<a name="line.1317"></a>
+<span class="sourceLineNo">1318</span>     */<a name="line.1318"></a>
+<span class="sourceLineNo">1319</span>    abstract int regionIndexToEntityIndex(int region);<a name="line.1319"></a>
+<span class="sourceLineNo">1320</span><a name="line.1320"></a>
+<span class="sourceLineNo">1321</span>    public void setServices(MasterServices srvc) {<a name="line.1321"></a>
+<span class="sourceLineNo">1322</span>      this.services = srvc;<a name="line.1322"></a>
+<span class="sourceLineNo">1323</span>    }<a name="line.1323"></a>
+<span class="sourceLineNo">1324</span><a name="line.1324"></a>
+<span class="sourceLineNo">1325</span>    @Override<a name="line.1325"></a>
+<span class="sourceLineNo">1326</span>    void init(Cluster cluster) {<a name="line.1326"></a>
+<span class="sourceLineNo">1327</span>      super.init(cluster);<a name="line.1327"></a>
+<span class="sourceLineNo">1328</span>      locality = 0.0;<a name="line.1328"></a>
+<span class="sourceLineNo">1329</span>      bestLocality = 0.0;<a name="line.1329"></a>
+<span class="sourceLineNo">1330</span><a name="line.1330"></a>
+<span class="sourceLineNo">1331</span>      // If no master, no computation will work, so assume 0 cost<a name="line.1331"></a>
+<span class="sourceLineNo">1332</span>      if (this.services == null) {<a name="line.1332"></a>
+<span class="sourceLineNo">1333</span>        return;<a name="line.1333"></a>
+<span class="sourceLineNo">1334</span>      }<a name="line.1334"></a>
+<span class="sourceLineNo">1335</span><a name="line.1335"></a>
+<span class="sourceLineNo">1336</span>      for (int region = 0; region &lt; cluster.numRegions; region++) {<a name="line.1336"></a>
+<span class="sourceLineNo">1337</span>        locality += getWeightedLocality(region, regionIndexToEntityIndex(region));<a name="line.1337"></a>
+<span class="sourceLineNo">1338</span>        bestLocality += getWeightedLocality(region, getMostLocalEntityForRegion(region));<a name="line.1338"></a>
+<span class="sourceLineNo">1339</span>      }<a name="line.1339"></a>
+<span class="sourceLineNo">1340</span><a name="line.1340"></a>
+<span class="sourceLineNo">1341</span>      // We normalize locality to be a score between 0 and 1.0 representing how good it<a name="line.1341"></a>
+<span class="sourceLineNo">1342</span>      // is compared to how good it could be. If bestLocality is 0, assume locality is 100<a name="line.1342"></a>
+<span class="sourceLineNo">1343</span>      // (and the cost is 0)<a name="line.1343"></a>
+<span class="sourceLineNo">1344</span>      locality = bestLocality == 0 ? 1.0 : locality / bestLocality;<a name="line.1344"></a>
+<span class="sourceLineNo">1345</span>    }<a name="line.1345"></a>
+<span class="sourceLineNo">1346</span><a name="line.1346"></a>
+<span class="sourceLineNo">1347</span>    @Override<a name="line.1347"></a>
+<span class="sourceLineNo">1348</span>    protected void regionMoved(int region, int oldServer, int newServer) {<a name="line.1348"></a>
+<span class="sourceLineNo">1349</span>      int oldEntity = type == LocalityType.SERVER ? oldServer : cluster.serverIndexToRackIndex[oldServer];<a name="line.1349"></a>
+<span class="sourceLineNo">1350</span>      int newEntity = type == LocalityType.SERVER ? newServer : cluster.serverIndexToRackIndex[newServer];<a name="line.1350"></a>
+<span class="sourceLineNo">1351</span>      if (this.services == null) {<a name="line.1351"></a>
+<span class="sourceLineNo">1352</span>        return;<a name="line.1352"></a>
+<span class="sourceLineNo">1353</span>      }<a name="line.1353"></a>
+<span class="sourceLineNo">1354</span>      double localityDelta = getWeightedLocality(region, newEntity) - getWeightedLocality(region, oldEntity);<a name="line.1354"></a>
+<span class="sourceLineNo">1355</span>      double normalizedDelta = bestLocality == 0 ? 0.0 : localityDelta / bestLocality;<a name="line.1355"></a>
+<span class="sourceLineNo">1356</span>      locality += normalizedDelta;<a name="line.1356"></a>
+<span class="sourceLineNo">1357</span>    }<a name="line.1357"></a>
+<span class="sourceLineNo">1358</span><a name="line.1358"></a>
+<span class="sourceLineNo">1359</span>    @Override<a name="line.1359"></a>
+<span class="sourceLineNo">1360</span>    protected double cost() {<a name="line.1360"></a>
+<span class="sourceLineNo">1361</span>      return 1 - locality;<a name="line.1361"></a>
+<span class="sourceLineNo">1362</span>    }<a name="line.1362"></a>
+<span class="sourceLineNo">1363</span><a name="line.1363"></a>
+<span class="sourceLineNo">1364</span>    private int getMostLocalEntityForRegion(int region) {<a name="line.1364"></a>
+<span class="sourceLineNo">1365</span>      return cluster.getOrComputeRegionsToMostLocalEntities(type)[region];<a name="line.1365"></a>
+<span class="sourceLineNo">1366</span>    }<a name="line.1366"></a>
+<span class="sourceLineNo">1367</span><a name="line.1367"></a>
+<span class="sourceLineNo">1368</span>    private double getWeightedLocality(int region, int entity) {<a name="line.1368"></a>
+<span class="sourceLineNo">1369</span>      return cluster.getOrComputeWeightedLocality(region, entity, type);<a name="line.1369"></a>
+<span class="sourceLineNo">1370</span>    }<a name="line.1370"></a>
 <span class="sourceLineNo">1371</span><a name="line.1371"></a>
-<span class="sourceLineNo">1372</span>  static class ServerLocalityCostFunction extends LocalityBasedCostFunction {<a name="line.1372"></a>
+<span class="sourceLineNo">1372</span>  }<a name="line.1372"></a>
 <span class="sourceLineNo">1373</span><a name="line.1373"></a>
-<span class="sourceLineNo">1374</span>    private static final String LOCALITY_COST_KEY = "hbase.master.balancer.stochastic.localityCost";<a name="line.1374"></a>
-<span class="sourceLineNo">1375</span>    private static final float DEFAULT_LOCALITY_COST = 25;<a name="line.1375"></a>
-<span class="sourceLineNo">1376</span><a name="line.1376"></a>
-<span class="sourceLineNo">1377</span>    ServerLocalityCostFunction(Configuration conf, MasterServices srv) {<a name="line.1377"></a>
-<span class="sourceLineNo">1378</span>      super(<a name="line.1378"></a>
-<span class="sourceLineNo">1379</span>          conf,<a name="line.1379"></a>
-<span class="sourceLineNo">1380</span>          srv,<a name="line.1380"></a>
-<span class="sourceLineNo">1381</span>          LocalityType.SERVER,<a name="line.1381"></a>
-<span class="sourceLineNo">1382</span>          LOCALITY_COST_KEY,<a name="line.1382"></a>
-<span class="sourceLineNo">1383</span>          DEFAULT_LOCALITY_COST<a name="line.1383"></a>
-<span class="sourceLineNo">1384</span>      );<a name="line.1384"></a>
-<span class="sourceLineNo">1385</span>    }<a name="line.1385"></a>
-<span class="sourceLineNo">1386</span><a name="line.1386"></a>
-<span class="sourceLineNo">1387</span>    @Override<a name="line.1387"></a>
-<span class="sourceLineNo">1388</span>    int regionIndexToEntityIndex(int region) {<a name="line.1388"></a>
-<span class="sourceLineNo">1389</span>      return cluster.regionIndexToServerIndex[region];<a name="line.1389"></a>
-<span class="sourceLineNo">1390</span>    }<a name="line.1390"></a>
-<span class="sourceLineNo">1391</span>  }<a name="line.1391"></a>
-<span class="sourceLineNo">1392</span><a name="line.1392"></a>
-<span class="sourceLineNo">1393</span>  static class RackLocalityCostFunction extends LocalityBasedCostFunction {<a name="line.1393"></a>
+<span class="sourceLineNo">1374</span>  static class ServerLocalityCostFunction extends LocalityBasedCostFunction {<a name="line.1374"></a>
+<span class="sourceLineNo">1375</span><a name="line.1375"></a>
+<span class="sourceLineNo">1376</span>    private static final String LOCALITY_COST_KEY = "hbase.master.balancer.stochastic.localityCost";<a name="line.1376"></a>
+<span class="sourceLineNo">1377</span>    private static final float DEFAULT_LOCALITY_COST = 25;<a name="line.1377"></a>
+<span class="sourceLineNo">1378</span><a name="line.1378"></a>
+<span class="sourceLineNo">1379</span>    ServerLocalityCostFunction(Configuration conf, MasterServices srv) {<a name="line.1379"></a>
+<span class="sourceLineNo">1380</span>      super(<a name="line.1380"></a>
+<span class="sourceLineNo">1381</span>          conf,<a name="line.1381"></a>
+<span class="sourceLineNo">1382</span>          srv,<a name="line.1382"></a>
+<span class="sourceLineNo">1383</span>          LocalityType.SERVER,<a name="line.1383"></a>
+<span class="sourceLineNo">1384</span>          LOCALITY_COST_KEY,<a name="line.1384"></a>
+<span class="sourceLineNo">1385</span>          DEFAULT_LOCALITY_COST<a name="line.1385"></a>
+<span class="sourceLineNo">1386</span>      );<a name="line.1386"></a>
+<span class="sourceLineNo">1387</span>    }<a name="line.1387"></a>
+<span class="sourceLineNo">1388</span><a name="line.1388"></a>
+<span class="sourceLineNo">1389</span>    @Override<a name="line.1389"></a>
+<span class="sourceLineNo">1390</span>    int regionIndexToEntityIndex(int region) {<a name="line.1390"></a>
+<span class="sourceLineNo">1391</span>      return cluster.regionIndexToServerIndex[region];<a name="line.1391"></a>
+<span class="sourceLineNo">1392</span>    }<a name="line.1392"></a>
+<span class="sourceLineNo">1393</span>  }<a name="line.1393"></a>
 <span class="sourceLineNo">1394</span><a name="line.1394"></a>
-<span class="sourceLineNo">1395</span>    private static final String RACK_LOCALITY_COST_KEY = "hbase.master.balancer.stochastic.rackLocalityCost";<a name="line.1395"></a>
-<span class="sourceLineNo">1396</span>    private static final float DEFAULT_RACK_LOCALITY_COST = 15;<a name="line.1396"></a>
-<span class="sourceLineNo">1397</span><a name="line.1397"></a>
-<span class="sourceLineNo">1398</span>    public RackLocalityCostFunction(Configuration conf, MasterServices services) {<a name="line.1398"></a>
-<span class="sourceLineNo">1399</span>      super(<a name="line.1399"></a>
-<span class="sourceLineNo">1400</span>          conf,<a name="line.1400"></a>
-<span class="sourceLineNo">1401</span>          services,<a name="line.1401"></a>
-<span class="sourceLineNo">1402</span>          LocalityType.RACK,<a name="line.1402"></a>
-<span class="sourceLineNo">1403</span>          RACK_LOCALITY_COST_KEY,<a name="line.1403"></a>
-<span class="sourceLineNo">1404</span>          DEFAULT_RACK_LOCALITY_COST<a name="line.1404"></a>
-<span class="sourceLineNo">1405</span>      );<a name="line.1405"></a>
-<span class="sourceLineNo">1406</span>    }<a name="line.1406"></a>
-<span class="sourceLineNo">1407</span><a name="line.1407"></a>
-<span class="sourceLineNo">1408</span>    @Override<a name="line.1408"></a>
-<span class="sourceLineNo">1409</span>    int regionIndexToEntityIndex(int region) {<a name="line.1409"></a>
-<span class="sourceLineNo">1410</span>      return cluster.getRackForRegion(region);<a name="line.1410"></a>
-<span class="sourceLineNo">1411</span>    }<a name="line.1411"></a>
-<span class="sourceLineNo">1412</span>  }<a name="line.1412"></a>
-<span class="sourceLineNo">1413</span><a name="line.1413"></a>
-<span class="sourceLineNo">1414</span>  /**<a name="line.1414"></a>
-<span class="sourceLineNo">1415</span>   * Base class the allows writing costs functions from rolling average of some<a name="line.1415"></a>
-<span class="sourceLineNo">1416</span>   * number from RegionLoad.<a name="line.1416"></a>
-<span class="sourceLineNo">1417</span>   */<a name="line.1417"></a>
-<span class="sourceLineNo">1418</span>  abstract static class CostFromRegionLoadFunction extends CostFunction {<a name="line.1418"></a>
-<span class="sourceLineNo">1419</span><a name="line.1419"></a>
-<span class="sourceLineNo">1420</span>    private ClusterMetrics clusterStatus = null;<a name="line.1420"></a>
-<span class="sourceLineNo">1421</span>    private Map&lt;String, Deque&lt;BalancerRegionLoad&gt;&gt; loads = null;<a name="line.1421"></a>
-<span class="sourceLineNo">1422</span>    private double[] stats = null;<a name="line.1422"></a>
-<span class="sourceLineNo">1423</span>    CostFromRegionLoadFunction(Configuration conf) {<a name="line.1423"></a>
-<span class="sourceLineNo">1424</span>      super(conf);<a name="line.1424"></a>
-<span class="sourceLineNo">1425</span>    }<a name="line.1425"></a>
-<span class="sourceLineNo">1426</span><a name="line.1426"></a>
-<span class="sourceLineNo">1427</span>    void setClusterMetrics(ClusterMetrics status) {<a name="line.1427"></a>
-<span class="sourceLineNo">1428</span>      this.clusterStatus = status;<a name="line.1428"></a>
-<span class="sourceLineNo">1429</span>    }<a name="line.1429"></a>
-<span class="sourceLineNo">1430</span><a name="line.1430"></a>
-<span class="sourceLineNo">1431</span>    void setLoads(Map&lt;String, Deque&lt;BalancerRegionLoad&gt;&gt; l) {<a name="line.1431"></a>
-<span class="sourceLineNo">1432</span>      this.loads = l;<a name="line.1432"></a>
-<span class="sourceLineNo">1433</span>    }<a name="line.1433"></a>
-<span class="sourceLineNo">1434</span><a name="line.1434"></a>
-<span class="sourceLineNo">1435</span>    @Override<a name="line.1435"></a>
-<span class="sourceLineNo">1436</span>    protected double cost() {<a name="line.1436"></a>
-<span class="sourceLineNo">1437</span>      if (clusterStatus == null || loads == null) {<a name="line.1437"></a>
-<span class="sourceLineNo">1438</span>        return 0;<a name="line.1438"></a>
-<span class="sourceLineNo">1439</span>      }<a name="line.1439"></a>
-<span class="sourceLineNo">1440</span><a name="line.1440"></a>
-<span class="sourceLineNo">1441</span>      if (stats == null || stats.length != cluster.numServers) {<a name="line.1441"></a>
-<span class="sourceLineNo">1442</span>        stats = new double[cluster.numServers];<a name="line.1442"></a>
-<span class="sourceLineNo">1443</span>      }<a name="line.1443"></a>
-<span class="sourceLineNo">1444</span><a name="line.1444"></a>
-<span class="sourceLineNo">1445</span>      for (int i =0; i &lt; stats.length; i++) {<a name="line.1445"></a>
-<span class="sourceLineNo">1446</span>        //Cost this server has from RegionLoad<a name="line.1446"></a>
-<span class="sourceLineNo">1447</span>        long cost = 0;<a name="line.1447"></a>
-<span class="sourceLineNo">1448</span><a name="line.1448"></a>
-<span class="sourceLineNo">1449</span>        // for every region on this server get the rl<a name="line.1449"></a>
-<span class="sourceLineNo">1450</span>        for(int regionIndex:cluster.regionsPerServer[i]) {<a name="line.1450"></a>
-<span class="sourceLineNo">1451</span>          Collection&lt;BalancerRegionLoad&gt; regionLoadList =  cluster.regionLoads[regionIndex];<a name="line.1451"></a>
-<span class="sourceLineNo">1452</span><a name="line.1452"></a>
-<span class="sourceLineNo">1453</span>          // Now if we found a region load get the type of cost that was requested.<a name="line.1453"></a>
-<span class="sourceLineNo">1454</span>          if (regionLoadList != null) {<a name="line.1454"></a>
-<span class="sourceLineNo">1455</span>            cost = (long) (cost + getRegionLoadCost(regionLoadList));<a name="line.1455"></a>
-<span class="sourceLineNo">1456</span>          }<a name="line.1456"></a>
-<span class="sourceLineNo">1457</span>        }<a name="line.1457"></a>
-<span class="sourceLineNo">1458</span><a name="line.1458"></a>
-<span class="sourceLineNo">1459</span>        // Add the total cost to the stats.<a name="line.1459"></a>
-<span class="sourceLineNo">1460</span>        stats[i] = cost;<a name="line.1460"></a>
-<span class="sourceLineNo">1461</span>      }<a name="line.1461"></a>
-<span class="sourceLineNo">1462</span><a name="line.1462"></a>
-<span class="sourceLineNo">1463</span>      // Now return the scaled cost from data held in the stats object.<a name="line.1463"></a>
-<span class="sourceLineNo">1464</span>      return costFromArray(stats);<a name="line.1464"></a>
-<span class="sourceLineNo">1465</span>    }<a name="line.1465"></a>
-<span class="sourceLineNo">1466</span><a name="line.1466"></a>
-<span class="sourceLineNo">1467</span>    protected double getRegionLoadCost(Collection&lt;BalancerRegionLoad&gt; regionLoadList) {<a name="line.1467"></a>
-<span class="sourceLineNo">1468</span>      double cost = 0;<a name="line.1468"></a>
-<span class="sourceLineNo">1469</span>      for (BalancerRegionLoad rl : regionLoadList) {<a name="line.1469"></a>
-<span class="sourceLineNo">1470</span>        cost += getCostFromRl(rl);<a name="line.1470"></a>
-<span class="sourceLineNo">1471</span>      }<a name="line.1471"></a>
-<span class="sourceLineNo">1472</span>      return cost / regionLoadList.size();<a name="line.1472"></a>
-<span class="sourceLineNo">1473</span>    }<a name="line.1473"></a>
-<span class="sourceLineNo">1474</span><a name="line.1474"></a>
-<span class="sourceLineNo">1475</span>    protected abstract double getCostFromRl(BalancerRegionLoad rl);<a name="line.1475"></a>
-<span class="sourceLineNo">1476</span>  }<a name="line.1476"></a>
-<span class="sourceLineNo">1477</span><a name="line.1477"></a>
-<span class="sourceLineNo">1478</span>  /**<a name="line.1478"></a>
-<span class="sourceLineNo">1479</span>   * Class to be used for the subset of RegionLoad costs that should be treated as rates.<a name="line.1479"></a>
-<span class="sourceLineNo">1480</span>   * We do not compare about the actual rate in requests per second but rather the rate relative<a name="line.1480"></a>
-<span class="sourceLineNo">1481</span>   * to the rest of the regions.<a name="line.1481"></a>
-<span class="sourceLineNo">1482</span>   */<a name="line.1482"></a>
-<span class="sourceLineNo">1483</span>  abstract static class CostFromRegionLoadAsRateFunction extends CostFromRegionLoadFunction {<a name="line.1483"></a>
-<span class="sourceLineNo">1484</span><a name="line.1484"></a>
-<span class="sourceLineNo">1485</span>    CostFromRegionLoadAsRateFunction(Configuration conf) {<a name="line.1485"></a>
-<span class="sourceLineNo">1486</span>      super(conf);<a name="line.1486"></a>
-<span class="sourceLineNo">1487</span>    }<a name="line.1487"></a>
-<span class="sourceLineNo">1488</span><a name="line.1488"></a>
-<span class="sourceLineNo">1489</span>    @Override<a name="line.1489"></a>
-<span class="sourceLineNo">1490</span>    protected double getRegionLoadCost(Collection&lt;BalancerRegionLoad&gt; regionLoadList) {<a name="line.1490"></a>
-<span class="sourceLineNo">1491</span>      double cost = 0;<a name="line.1491"></a>
-<span class="sourceLineNo">1492</span>      double previous = 0;<a name="line.1492"></a>
-<span class="sourceLineNo">1493</span>      boolean isFirst = true;<a name="line.1493"></a>
-<span class="sourceLineNo">1494</span>      for (BalancerRegionLoad rl : regionLoadList) {<a name="line.1494"></a>
-<span class="sourceLineNo">1495</span>        double current = getCostFromRl(rl);<a name="line.1495"></a>
-<span class="sourceLineNo">1496</span>        if (isFirst) {<a name="line.1496"></a>
-<span class="sourceLineNo">1497</span>          isFirst = false;<a name="line.1497"></a>
-<span class="sourceLineNo">1498</span>        } else {<a name="line.1498"></a>
-<span class="sourceLineNo">1499</span>          cost += current - previous;<a name="line.1499"></a>
-<span class="sourceLineNo">1500</span>        }<a name="line.1500"></a>
-<span class="sourceLineNo">1501</span>        previous = current;<a name="line.1501"></a>
-<span class="sourceLineNo">1502</span>      }<a name="line.1502"></a>
-<span class="sourceLineNo">1503</span>      return Math.max(0, cost / (regionLoadList.size() - 1));<a name="line.1503"></a>
-<span class="sourceLineNo">1504</span>    }<a name="line.1504"></a>
-<span class="sourceLineNo">1505</span>  }<a name="line.1505"></a>
-<span class="sourceLineNo">1506</span><a name="line.1506"></a>
-<span class="sourceLineNo">1507</span>  /**<a name="line.1507"></a>
-<span class="sourceLineNo">1508</span>   * Compute the cost of total number of read requests  The more unbalanced the higher the<a name="line.1508"></a>
-<span class="sourceLineNo">1509</span>   * computed cost will be.  This uses a rolling average of regionload.<a name="line.1509"></a>
-<span class="sourceLineNo">1510</span>   */<a name="line.1510"></a>
-<span class="sourceLineNo">1511</span><a name="line.1511"></a>
-<span class="sourceLineNo">1512</span>  static class ReadRequestCostFunction extends CostFromRegionLoadAsRateFunction {<a name="line.1512"></a>
+<span class="sourceLineNo">1395</span>  static class RackLocalityCostFunction extends LocalityBasedCostFunction {<a name="line.1395"></a>
+<span class="sourceLineNo">1396</span><a name="line.1396"></a>
+<span class="sourceLineNo">1397</span>    private static final String RACK_LOCALITY_COST_KEY = "hbase.master.balancer.stochastic.rackLocalityCost";<a name="line.1397"></a>
+<span class="sourceLineNo">1398</span>    private static final float DEFAULT_RACK_LOCALITY_COST = 15;<a name="line.1398"></a>
+<span class="sourceLineNo">1399</span><a name="line.1399"></a>
+<span class="sourceLineNo">1400</span>    public RackLocalityCostFunction(Configuration conf, MasterServices services) {<a name="line.1400"></a>
+<span class="sourceLineNo">1401</span>      super(<a name="line.1401"></a>
+<span class="sourceLineNo">1402</span>          conf,<a name="line.1402"></a>
+<span class="sourceLineNo">1403</span>          services,<a name="line.1403"></a>
+<span class="sourceLineNo">1404</span>          LocalityType.RACK,<a name="line.1404"></a>
+<span class="sourceLineNo">1405</span>          RACK_LOCALITY_COST_KEY,<a name="line.1405"></a>
+<span class="sourceLineNo">1406</span>          DEFAULT_RACK_LOCALITY_COST<a name="line.1406"></a>
+<span class="sourceLineNo">1407</span>      );<a name="line.1407"></a>
+<span class="sourceLineNo">1408</span>    }<a name="line.1408"></a>
+<span class="sourceLineNo">1409</span><a name="line.1409"></a>
+<span class="sourceLineNo">1410</span>    @Override<a name="line.1410"></a>
+<span class="sourceLineNo">1411</span>    int regionIndexToEntityIndex(int region) {<a name="line.1411"></a>
+<span class="sourceLineNo">1412</span>      return cluster.getRackForRegion(region);<a name="line.1412"></a>
+<span class="sourceLineNo">1413</span>    }<a name="line.1413"></a>
+<span class="sourceLineNo">1414</span>  }<a name="line.1414"></a>
+<span class="sourceLineNo">1415</span><a name="line.1415"></a>
+<span class="sourceLineNo">1416</span>  /**<a name="line.1416"></a>
+<span class="sourceLineNo">1417</span>   * Base class the allows writing costs functions from rolling average of some<a name="line.1417"></a>
+<span class="sourceLineNo">1418</span>   * number from RegionLoad.<a name="line.1418"></a>
+<span class="sourceLineNo">1419</span>   */<a name="line.1419"></a>
+<span class="sourceLineNo">1420</span>  abstract static class CostFromRegionLoadFunction extends CostFunction {<a name="line.1420"></a>
+<span class="sourceLineNo">1421</span><a name="line.1421"></a>
+<span class="sourceLineNo">1422</span>    private ClusterMetrics clusterStatus = null;<a name="line.1422"></a>
+<span class="sourceLineNo">1423</span>    private Map&lt;String, Deque&lt;BalancerRegionLoad&gt;&gt; loads = null;<a name="line.1423"></a>
+<span class="sourceLineNo">1424</span>    private double[] stats = null;<a name="line.1424"></a>
+<span class="sourceLineNo">1425</span>    CostFromRegionLoadFunction(Configuration conf) {<a name="line.1425"></a>
+<span class="sourceLineNo">1426</span>      super(conf);<a name="line.1426"></a>
+<span class="sourceLineNo">1427</span>    }<a name="line.1427"></a>
+<span class="sourceLineNo">1428</span><a name="line.1428"></a>
+<span class="sourceLineNo">1429</span>    void setClusterMetrics(ClusterMetrics status) {<a name="line.1429"></a>
+<span class="sourceLineNo">1430</span>      this.clusterStatus = status;<a name="line.1430"></a>
+<span class="sourceLineNo">1431</span>    }<a name="line.1431"></a>
+<span class="sourceLineNo">1432</span><a name="line.1432"></a>
+<span class="sourceLineNo">1433</span>    void setLoads(Map&lt;String, Deque&lt;BalancerRegionLoad&gt;&gt; l) {<a name="line.1433"></a>
+<span class="sourceLineNo">1434</span>      this.loads = l;<a name="line.1434"></a>
+<span class="sourceLineNo">1435</span>    }<a name="line.1435"></a>
+<span class="sourceLineNo">1436</span><a name="line.1436"></a>
+<span class="sourceLineNo">1437</span>    @Override<a name="line.1437"></a>
+<span class="sourceLineNo">1438</span>    protected double cost() {<a name="line.1438"></a>
+<span class="sourceLineNo">1439</span>      if (clusterStatus == null || loads == null) {<a name="line.1439"></a>
+<span class="sourceLineNo">1440</span>        return 0;<a name="line.1440"></a>
+<span class="sourceLineNo">1441</span>      }<a name="line.1441"></a>
+<span class="sourceLineNo">1442</span><a name="line.1442"></a>
+<span class="sourceLineNo">1443</span>      if (stats == null || stats.length != cluster.numServers) {<a name="line.1443"></a>
+<span class="sourceLineNo">1444</span>        stats = new double[cluster.numServers];<a name="line.1444"></a>
+<span class="sourceLineNo">1445</span>      }<a name="line.1445"></a>
+<span class="sourceLineNo">1446</span><a name="line.1446"></a>
+<span class="sourceLineNo">1447</span>      for (int i =0; i &lt; stats.length; i++) {<a name="line.1447"></a>
+<span class="sourceLineNo">1448</span>        //Cost this server has from RegionLoad<a name="line.1448"></a>
+<span class="sourceLineNo">1449</span>        long cost = 0;<a name="line.1449"></a>
+<span class="sourceLineNo">1450</span><a name="line.1450"></a>
+<span class="sourceLineNo">1451</span>        // for every region on this server get the rl<a name="line.1451"></a>
+<span class="sourceLineNo">1452</span>        for(int regionIndex:cluster.regionsPerServer[i]) {<a name="line.1452"></a>
+<span class="sourceLineNo">1453</span>          Collection&lt;BalancerRegionLoad&gt; regionLoadList =  cluster.regionLoads[regionIndex];<a name="line.1453"></a>
+<span class="sourceLineNo">1454</span><a name="line.1454"></a>
+<span class="sourceLineNo">1455</span>          // Now if we found a region load get the type of cost that was requested.<a name="line.1455"></a>
+<span class="sourceLineNo">1456</span>          if (regionLoadList != null) {<a name="line.1456"></a>
+<span class="sourceLineNo">1457</span>            cost = (long) (cost + getRegionLoadCost(regionLoadList));<a name="line.1457"></a>
+<span class="sourceLineNo">1458</span>          }<a name="line.1458"></a>
+<span class="sourceLineNo">1459</span>        }<a name="line.1459"></a>
+<span class="sourceLineNo">1460</span><a name="line.1460"></a>
+<span class="sourceLineNo">1461</span>        // Add the total cost to the stats.<a name="line.1461"></a>
+<span class="sourceLineNo">1462</span>        stats[i] = cost;<a name="line.1462"></a>
+<span class="sourceLineNo">1463</span>      }<a name="line.1463"></a>
+<span class="sourceLineNo">1464</span><a name="line.1464"></a>
+<span class="sourceLineNo">1465</span>      // Now return the scaled cost from data held in the stats object.<a name="line.1465"></a>
+<span class="sourceLineNo">1466</span>      return costFromArray(stats);<a name="line.1466"></a>
+<span class="sourceLineNo">1467</span>    }<a name="line.1467"></a>
+<span class="sourceLineNo">1468</span><a name="line.1468"></a>
+<span class="sourceLineNo">1469</span>    protected double getRegionLoadCost(Collection&lt;BalancerRegionLoad&gt; regionLoadList) {<a name="line.1469"></a>
+<span class="sourceLineNo">1470</span>      double cost = 0;<a name="line.1470"></a>
+<span class="sourceLineNo">1471</span>      for (BalancerRegionLoad rl : regionLoadList) {<a name="line.1471"></a>
+<span class="sourceLineNo">1472</span>        cost += getCostFromRl(rl);<a name="line.1472"></a>
+<span class="sourceLineNo">1473</span>      }<a name="line.1473"></a>
+<span class="sourceLineNo">1474</span>      return cost / regionLoadList.size();<a name="line.1474"></a>
+<span class="sourceLineNo">1475</span>    }<a name="line.1475"></a>
+<span class="sourceLineNo">1476</span><a name="line.1476"></a>
+<span class="sourceLineNo">1477</span>    protected abstract double getCostFromRl(BalancerRegionLoad rl);<a name="line.1477"></a>
+<span class="sourceLineNo">1478</span>  }<a name="line.1478"></a>
+<span class="sourceLineNo">1479</span><a name="line.1479"></a>
+<span class="sourceLineNo">1480</span>  /**<a name="line.1480"></a>
+<span class="sourceLineNo">1481</span>   * Class to be used for the subset of RegionLoad costs that should be treated as rates.<a name="line.1481"></a>
+<span class="sourceLineNo">1482</span>   * We do not compare about the actual rate in requests per second but rather the rate relative<a name="line.1482"></a>
+<span class="sourceLineNo">1483</span>   * to the rest of the regions.<a name="line.1483"></a>
+<span class="sourceLineNo">1484</span>   */<a name="line.1484"></a>
+<span class="sourceLineNo">1485</span>  abstract static class CostFromRegionLoadAsRateFunction extends CostFromRegionLoadFunction {<a name="line.1485"></a>
+<span class="sourceLineNo">1486</span><a name="line.1486"></a>
+<span class="sourceLineNo">1487</span>    CostFromRegionLoadAsRateFunction(Configuration conf) {<a name="line.1487"></a>
+<span class="sourceLineNo">1488</span>      super(conf);<a name="line.1488"></a>
+<span class="sourceLineNo">1489</span>    }<a name="line.1489"></a>
+<span class="sourceLineNo">1490</span><a name="line.1490"></a>
+<span class="sourceLineNo">1491</span>    @Override<a name="line.1491"></a>
+<span class="sourceLineNo">1492</span>    protected double getRegionLoadCost(Collection&lt;BalancerRegionLoad&gt; regionLoadList) {<a name="line.1492"></a>
+<span class="sourceLineNo">1493</span>      double cost = 0;<a name="line.1493"></a>
+<span class="sourceLineNo">1494</span>      double previous = 0;<a name="line.1494"></a>
+<span class="sourceLineNo">1495</span>      boolean isFirst = true;<a name="line.1495"></a>
+<span class="sourceLineNo">1496</span>      for (BalancerRegionLoad rl : regionLoadList) {<a name="line.1496"></a>
+<span class="sourceLineNo">1497</span>        double current = getCostFromRl(rl);<a name="line.1497"></a>
+<span class="sourceLineNo">1498</span>        if (isFirst) {<a name="line.1498"></a>
+<span class="sourceLineNo">1499</span>          isFirst = false;<a name="line.1499"></a>
+<span class="sourceLineNo">1500</span>        } else {<a name="line.1500"></a>
+<span class="sourceLineNo">1501</span>          cost += current - previous;<a name="line.1501"></a>
+<span class="sourceLineNo">1502</span>        }<a name="line.1502"></a>
+<span class="sourceLineNo">1503</span>        previous = current;<a name="line.1503"></a>
+<span class="sourceLineNo">1504</span>      }<a name="line.1504"></a>
+<span class="sourceLineNo">1505</span>      return Math.max(0, cost / (regionLoadList.size() - 1));<a name="line.1505"></a>
+<span class="sourceLineNo">1506</span>    }<a name="line.1506"></a>
+<span class="sourceLineNo">1507</span>  }<a name="line.1507"></a>
+<span class="sourceLineNo">1508</span><a name="line.1508"></a>
+<span class="sourceLineNo">1509</span>  /**<a name="line.1509"></a>
+<span class="sourceLineNo">1510</span>   * Compute the cost of total number of read requests  The more unbalanced the higher the<a name="line.1510"></a>
+<span class="sourceLineNo">1511</span>   * computed cost will be.  This uses a rolling average of regionload.<a name="line.1511"></a>
+<span class="sourceLineNo">1512</span>   */<a name="line.1512"></a>
 <span class="sourceLineNo">1513</span><a name="line.1513"></a>
-<span class="sourceLineNo">1514</span>    private static final String READ_REQUEST_COST_KEY =<a name="line.1514"></a>
-<span class="sourceLineNo">1515</span>        "hbase.master.balancer.stochastic.readRequestCost";<a name="line.1515"></a>
-<span class="sourceLineNo">1516</span>    private static final float DEFAULT_READ_REQUEST_COST = 5;<a name="line.1516"></a>
-<span class="sourceLineNo">1517</span><a name="line.1517"></a>
-<span class="sourceLineNo">1518</span>    ReadRequestCostFunction(Configuration conf) {<a name="line.1518"></a>
-<span class="sourceLineNo">1519</span>      super(conf);<a name="line.1519"></a>
-<span class="sourceLineNo">1520</span>      this.setMultiplier(conf.getFloat(READ_REQUEST_COST_KEY, DEFAULT_READ_REQUEST_COST));<a name="line.1520"></a>
-<span class="sourceLineNo">1521</span>    }<a name="line.1521"></a>
-<span class="sourceLineNo">1522</span><a name="line.1522"></a>
-<span class="sourceLineNo">1523</span>    @Override<a name="line.1523"></a>
-<span class="sourceLineNo">1524</span>    protected double getCostFromRl(BalancerRegionLoad rl) {<a name="line.1524"></a>
-<span class="sourceLineNo">1525</span>      return rl.getReadRequestsCount();<a name="line.1525"></a>
-<span class="sourceLineNo">1526</span>    }<a name="line.1526"></a>
-<span class="sourceLineNo">1527</span>  }<a name="line.1527"></a>
-<span class="sourceLineNo">1528</span><a name="line.1528"></a>
-<span class="sourceLineNo">1529</span>  /**<a name="line.1529"></a>
-<span class="sourceLineNo">1530</span>   * Compute the cost of total number of coprocessor requests  The more unbalanced the higher the<a name="line.1530"></a>
-<span class="sourceLineNo">1531</span>   * computed cost will be.  This uses a rolling average of regionload.<a name="line.1531"></a>
-<span class="sourceLineNo">1532</span>   */<a name="line.1532"></a>
-<span class="sourceLineNo">1533</span><a name="line.1533"></a>
-<span class="sourceLineNo">1534</span>  static class CPRequestCostFunction extends CostFromRegionLoadAsRateFunction {<a name="line.1534"></a>
+<span class="sourceLineNo">1514</span>  static class ReadRequestCostFunction extends CostFromRegionLoadAsRateFunction {<a name="line.1514"></a>
+<span class="sourceLineNo">1515</span><a name="line.1515"></a>
+<span class="sourceLineNo">1516</span>    private static final String READ_REQUEST_COST_KEY =<a name="line.1516"></a>
+<span class="sourceLineNo">1517</span>        "hbase.master.balancer.stochastic.readRequestCost";<a name="line.1517"></a>
+<span class="sourceLineNo">1518</span>    private static final float DEFAULT_READ_REQUEST_COST = 5;<a name="line.1518"></a>
+<span class="sourceLineNo">1519</span><a name="line.1519"></a>
+<span class="sourceLineNo">1520</span>    ReadRequestCostFunction(Configuration conf) {<a name="line.1520"></a>
+<span class="sourceLineNo">1521</span>      super(conf);<a name="line.1521"></a>
+<span class="sourceLineNo">1522</span>      this.setMultiplier(conf.getFloat(READ_REQUEST_COST_KEY, DEFAULT_READ_REQUEST_COST));<a name="line.1522"></a>
+<span class="sourceLineNo">1523</span>    }<a name="line.1523"></a>
+<span class="sourceLineNo">1524</span><a name="line.1524"></a>
+<span class="sourceLineNo">1525</span>    @Override<a name="line.1525"></a>
+<span class="sourceLineNo">1526</span>    protected double getCostFromRl(BalancerRegionLoad rl) {<a name="line.1526"></a>
+<span class="sourceLineNo">1527</span>      return rl.getReadRequestsCount();<a name="line.1527"></a>
+<span class="sourceLineNo">1528</span>    }<a name="line.1528"></a>
+<span class="sourceLineNo">1529</span>  }<a name="line.1529"></a>
+<span class="sourceLineNo">1530</span><a name="line.1530"></a>
+<span class="sourceLineNo">1531</span>  /**<a name="line.1531"></a>
+<span class="sourceLineNo">1532</span>   * Compute the cost of total number of coprocessor requests  The more unbalanced the higher the<a name="line.1532"></a>
+<span class="sourceLineNo">1533</span>   * computed cost will be.  This uses a rolling average of regionload.<a name="line.1533"></a>
+<span class="sourceLineNo">1534</span>   */<a name="line.1534"></a>
 <span class="sourceLineNo">1535</span><a name="line.1535"></a>
-<span class="sourceLineNo">1536</span>    private static final String CP_REQUEST_COST_KEY =<a name="line.1536"></a>
-<span class="sourceLineNo">1537</span>        "hbase.master.balancer.stochastic.cpRequestCost";<a name="line.1537"></a>
-<span class="sourceLineNo">1538</span>    private static final float DEFAULT_CP_REQUEST_COST = 5;<a name="line.1538"></a>
-<span class="sourceLineNo">1539</span><a name="line.1539"></a>
-<span class="sourceLineNo">1540</span>    CPRequestCostFunction(Configuration conf) {<a name="line.1540"></a>
-<span class="sourceLineNo">1541</span>      super(conf);<a name="line.1541"></a>
-<span class="sourceLineNo">1542</span>      this.setMultiplier(conf.getFloat(CP_REQUEST_COST_KEY, DEFAULT_CP_REQUEST_COST));<a name="line.1542"></a>
-<span class="sourceLineNo">1543</span>    }<a name="line.1543"></a>
-<span class="sourceLineNo">1544</span><a name="line.1544"></a>
-<span class="sourceLineNo">1545</span>    @Override<a name="line.1545"></a>
-<span class="sourceLineNo">1546</span>    protected double getCostFromRl(BalancerRegionLoad rl) {<a name="line.1546"></a>
-<span class="sourceLineNo">1547</span>      return rl.getCpRequestsCount();<a name="line.1547"></a>
-<span class="sourceLineNo">1548</span>    }<a name="line.1548"></a>
-<span class="sourceLineNo">1549</span>  }<a name="line.1549"></a>
-<span class="sourceLineNo">1550</span><a name="line.1550"></a>
-<span class="sourceLineNo">1551</span>  /**<a name="line.1551"></a>
-<span class="sourceLineNo">1552</span>   * Compute the cost of total number of write requests.  The more unbalanced the higher the<a name="line.1552"></a>
-<span class="sourceLineNo">1553</span>   * computed cost will be.  This uses a rolling average of regionload.<a name="line.1553"></a>
-<span class="sourceLineNo">1554</span>   */<a name="line.1554"></a>
-<span class="sourceLineNo">1555</span>  static class WriteRequestCostFunction extends CostFromRegionLoadAsRateFunction {<a name="line.1555"></a>
-<span class="sourceLineNo">1556</span><a name="line.1556"></a>
-<span class="sourceLineNo">1557</span>    private static final String WRITE_REQUEST_COST_KEY =<a name="line.1557"></a>
-<span class="sourceLineNo">1558</span>        "hbase.master.balancer.stochastic.writeRequestCost";<a name="line.1558"></a>
-<span class="sourceLineNo">1559</span>    private static final float DEFAULT_WRITE_REQUEST_COST = 5;<a name="line.1559"></a>
-<span class="sourceLineNo">1560</span><a name="line.1560"></a>
-<span class="sourceLineNo">1561</span>    WriteRequestCostFunction(Configuration conf) {<a name="line.1561"></a>
-<span class="sourceLineNo">1562</span>      super(conf);<a name="line.1562"></a>
-<span class="sourceLineNo">1563</span>      this.setMultiplier(conf.getFloat(WRITE_REQUEST_COST_KEY, DEFAULT_WRITE_REQUEST_COST));<a name="line.1563"></a>
-<span class="sourceLineNo">1564</span>    }<a name="line.1564"></a>
-<span class="sourceLineNo">1565</span><a name="line.1565"></a>
-<span class="sourceLineNo">1566</span>    @Override<a name="line.1566"></a>
-<span class="sourceLineNo">1567</span>    protected double getCostFromRl(BalancerRegionLoad rl) {<a name="line.1567"></a>
-<span class="sourceLineNo">1568</span>      return rl.getWriteRequestsCount();<a name="line.1568"></a>
-<span class="sourceLineNo">1569</span>    }<a name="line.1569"></a>
-<span class="sourceLineNo">1570</span>  }<a name="line.1570"></a>
-<span class="sourceLineNo">1571</span><a name="line.1571"></a>
-<span class="sourceLineNo">1572</span>  /**<a name="line.1572"></a>
-<span class="sourceLineNo">1573</span>   * A cost function for region replicas. We give a very high cost to hosting<a name="line.1573"></a>
-<span class="sourceLineNo">1574</span>   * replicas of the same region in the same host. We do not prevent the case<a name="line.1574"></a>
-<span class="sourceLineNo">1575</span>   * though, since if numReplicas &gt; numRegionServers, we still want to keep the<a name="line.1575"></a>
-<span class="sourceLineNo">1576</span>   * replica open.<a name="line.1576"></a>
-<span class="sourceLineNo">1577</span>   */<a name="line.1577"></a>
-<span class="sourceLineNo">1578</span>  static class RegionReplicaHostCostFunction extends CostFunction {<a name="line.1578"></a>
-<span class="sourceLineNo">1579</span>    private static final String REGION_REPLICA_HOST_COST_KEY =<a name="line.1579"></a>
-<span class="sourceLineNo">1580</span>        "hbase.master.balancer.stochastic.regionReplicaHostCostKey";<a name="line.1580"></a>
-<span class="sourceLineNo">1581</span>    private static final float DEFAULT_REGION_REPLICA_HOST_COST_KEY = 100000;<a name="line.1581"></a>
-<span class="sourceLineNo">1582</span><a name="line.1582"></a>
-<span class="sourceLineNo">1583</span>    long maxCost = 0;<a name="line.1583"></a>
-<span class="sourceLineNo">1584</span>    long[] costsPerGroup; // group is either server, host or rack<a name="line.1584"></a>
-<span class="sourceLineNo">1585</span>    int[][] primariesOfRegionsPerGroup;<a name="line.1585"></a>
-<span class="sourceLineNo">1586</span><a name="line.1586"></a>
-<span class="sourceLineNo">1587</span>    public RegionReplicaHostCostFunction(Configuration conf) {<a name="line.1587"></a>
-<span class="sourceLineNo">1588</span>      super(conf);<a name="line.1588"></a>
-<span class="sourceLineNo">1589</span>      this.setMultiplier(conf.getFloat(REGION_REPLICA_HOST_COST_KEY,<a name="line.1589"></a>
-<span class="sourceLineNo">1590</span>        DEFAULT_REGION_REPLICA_HOST_COST_KEY));<a name="line.1590"></a>
-<span class="sourceLineNo">1591</span>    }<a name="line.1591"></a>
-<span class="sourceLineNo">1592</span><a name="line.1592"></a>
-<span class="sourceLineNo">1593</span>    @Override<a name="line.1593"></a>
-<span class="sourceLineNo">1594</span>    void init(Cluster cluster) {<a name="line.1594"></a>
-<span class="sourceLineNo">1595</span>      super.init(cluster);<a name="line.1595"></a>
-<span class="sourceLineNo">1596</span>      // max cost is the case where every region replica is hosted together regardless of host<a name="line.1596"></a>
-<span class="sourceLineNo">1597</span>      maxCost = cluster.numHosts &gt; 1 ? getMaxCost(cluster) : 0;<a name="line.1597"></a>
-<span class="sourceLineNo">1598</span>      costsPerGroup = new long[cluster.numHosts];<a name="line.1598"></a>
-<span class="sourceLineNo">1599</span>      primariesOfRegionsPerGroup = cluster.multiServersPerHost // either server based or host based<a name="line.1599"></a>
-<span class="sourceLineNo">1600</span>          ? cluster.primariesOfRegionsPerHost<a name="line.1600"></a>
-<span class="sourceLineNo">1601</span>          : cluster.primariesOfRegionsPerServer;<a name="line.1601"></a>
-<span class="sourceLineNo">1602</span>      for (int i = 0 ; i &lt; primariesOfRegionsPerGroup.length; i++) {<a name="line.1602"></a>
-<span class="sourceLineNo">1603</span>        costsPerGroup[i] = costPerGroup(primariesOfRegionsPerGroup[i]);<a name="line.1603"></a>
-<span class="sourceLineNo">1604</span>      }<a name="line.1604"></a>
-<span class="sourceLineNo">1605</span>    }<a name="line.1605"></a>
-<span class="sourceLineNo">1606</span><a name="line.1606"></a>
-<span class="sourceLineNo">1607</span>    long getMaxCost(Cluster cluster) {<a name="line.1607"></a>
-<span class="sourceLineNo">1608</span>      if (!cluster.hasRegionReplicas) {<a name="line.1608"></a>
-<span class="sourceLineNo">1609</span>        return 0; // short circuit<a name="line.1609"></a>
-<span class="sourceLineNo">1610</span>      }<a name="line.1610"></a>
-<span class="sourceLineNo">1611</span>      // max cost is the case where every region replica is hosted together regardless of host<a name="line.1611"></a>
-<span class="sourceLineNo">1612</span>      int[] primariesOfRegions = new int[cluster.numRegions];<a name="line.1612"></a>
-<span class="sourceLineNo">1613</span>      System.arraycopy(cluster.regionIndexToPrimaryIndex, 0, primariesOfRegions, 0,<a name="line.1613"></a>
-<span class="sourceLineNo">1614</span>          cluster.regions.length);<a name="line.1614"></a>
-<span class="sourceLineNo">1615</span><a name="line.1615"></a>
-<span class="sourceLineNo">1616</span>      Arrays.sort(primariesOfRegions);<a name="line.1616"></a>
+<span class="sourceLineNo">1536</span>  static class CPRequestCostFunction extends CostFromRegionLoadAsRateFunction {<a name="line.1536"></a>
+<span class="sourceLineNo">1537</span><a name="line.1537"></a>
+<span class="sourceLineNo">1538</span>    private static final String CP_REQUEST_COST_KEY =<a name="line.1538"></a>
+<span class="sourceLineNo">1539</span>        "hbase.master.balancer.stochastic.cpRequestCost";<a name="line.1539"></a>
+<span class="sourceLineNo">1540</span>    private static final float DEFAULT_CP_REQUEST_COST = 5;<a name="line.1540"></a>
+<span class="sourceLineNo">1541</span><a name="line.1541"></a>
+<span class="sourceLineNo">1542</span>    CPRequestCostFunction(Configuration conf) {<a name="line.1542"></a>
+<span class="sourceLineNo">1543</span>      super(conf);<a name="line.1543"></a>
+<span class="sourceLineNo">1544</span>      this.setMultiplier(conf.getFloat(CP_REQUEST_COST_KEY, DEFAULT_CP_REQUEST_COST));<a name="line.1544"></a>
+<span class="sourceLineNo">1545</span>    }<a name="line.1545"></a>
+<span class="sourceLineNo">1546</span><a name="line.1546"></a>
+<span class="sourceLineNo">1547</span>    @Override<a name="line.1547"></a>
+<span class="sourceLineNo">1548</span>    protected double getCostFromRl(BalancerRegionLoad rl) {<a name="line.1548"></a>
+<span class="sourceLineNo">1549</span>      return rl.getCpRequestsCount();<a name="line.1549"></a>
+<span class="sourceLineNo">1550</span>    }<a name="line.1550"></a>
+<span class="sourceLineNo">1551</span>  }<a name="line.1551"></a>
+<span class="sourceLineNo">1552</span><a name="line.1552"></a>
+<span class="sourceLineNo">1553</span>  /**<a name="line.1553"></a>
+<span class="sourceLineNo">1554</span>   * Compute the cost of total number of write requests.  The more unbalanced the higher the<a name="line.1554"></a>
+<span class="sourceLineNo">1555</span>   * computed cost will be.  This uses a rolling average of regionload.<a name="line.1555"></a>
+<span class="sourceLineNo">1556</span>   */<a name="line.1556"></a>
+<span class="sourceLineNo">1557</span>  static class WriteRequestCostFunction extends CostFromRegionLoadAsRateFunction {<a name="line.1557"></a>
+<span class="sourceLineNo">1558</span><a name="line.1558"></a>
+<span class="sourceLineNo">1559</span>    private static final String WRITE_REQUEST_COST_KEY =<a name="line.1559"></a>
+<span class="sourceLineNo">1560</span>        "hbase.master.balancer.stochastic.writeRequestCost";<a name="line.1560"></a>
+<span class="sourceLineNo">1561</span>    private static final float DEFAULT_WRITE_REQUEST_COST = 5;<a name="line.1561"></a>
+<span class="sourceLineNo">1562</span><a name="line.1562"></a>
+<span class="sourceLineNo">1563</span>    WriteRequestCostFunction(Configuration conf) {<a name="line.1563"></a>
+<span class="sourceLineNo">1564</span>      super(conf);<a name="line.1564"></a>
+<span class="sourceLineNo">1565</span>      this.setMultiplier(conf.getFloat(WRITE_REQUEST_COST_KEY, DEFAULT_WRITE_REQUEST_COST));<a name="line.1565"></a>
+<span class="sourceLineNo">1566</span>    }<a name="line.1566"></a>
+<span class="sourceLineNo">1567</span><a name="line.1567"></a>
+<span class="sourceLineNo">1568</span>    @Override<a name="line.1568"></a>
+<span class="sourceLineNo">1569</span>    protected double getCostFromRl(BalancerRegionLoad rl) {<a name="line.1569"></a>
+<span class="sourceLineNo">1570</span>      return rl.getWriteRequestsCount();<a name="line.1570"></a>
+<span class="sourceLineNo">1571</span>    }<a name="line.1571"></a>
+<span class="sourceLineNo">1572</span>  }<a name="line.1572"></a>
+<span class="sourceLineNo">1573</span><a name="line.1573"></a>
+<span class="sourceLineNo">1574</span>  /**<a name="line.1574"></a>
+<span class="sourceLineNo">1575</span>   * A cost function for region replicas. We give a very high cost to hosting<a name="line.1575"></a>
+<span class="sourceLineNo">1576</span>   * replicas of the same region in the same host. We do not prevent the case<a name="line.1576"></a>
+<span class="sourceLineNo">1577</span>   * though, since if numReplicas &gt; numRegionServers, we still want to keep the<a name="line.1577"></a>
+<span class="sourceLineNo">1578</span>   * replica open.<a name="line.1578"></a>
+<span class="sourceLineNo">1579</span>   */<a name="line.1579"></a>
+<span class="sourceLineNo">1580</span>  static class RegionReplicaHostCostFunction extends CostFunction {<a name="line.1580"></a>
+<span class="sourceLineNo">1581</span>    private static final String REGION_REPLICA_HOST_COST_KEY =<a name="line.1581"></a>
+<span class="sourceLineNo">1582</span>        "hbase.master.balancer.stochastic.regionReplicaHostCostKey";<a name="line.1582"></a>
+<span class="sourceLineNo">1583</span>    private static final float DEFAULT_REGION_REPLICA_HOST_COST_KEY = 100000;<a name="line.1583"></a>
+<span class="sourceLineNo">1584</span><a name="line.1584"></a>
+<span class="sourceLineNo">1585</span>    long maxCost = 0;<a name="line.1585"></a>
+<span class="sourceLineNo">1586</span>    long[] costsPerGroup; // group is either server, host or rack<a name="line.1586"></a>
+<span class="sourceLineNo">1587</span>    int[][] primariesOfRegionsPerGroup;<a name="line.1587"></a>
+<span class="sourceLineNo">1588</span><a name="line.1588"></a>
+<span class="sourceLineNo">1589</span>    public RegionReplicaHostCostFunction(Configuration conf) {<a name="line.1589"></a>
+<span class="sourceLineNo">1590</span>      super(conf);<a name="line.1590"></a>
+<span class="sourceLineNo">1591</span>      this.setMultiplier(conf.getFloat(REGION_REPLICA_HOST_COST_KEY,<a name="line.1591"></a>
+<span class="sourceLineNo">1592</span>        DEFAULT_REGION_REPLICA_HOST_COST_KEY));<a name="line.1592"></a>
+<span class="sourceLineNo">1593</span>    }<a name="line.1593"></a>
+<span class="sourceLineNo">1594</span><a name="line.1594"></a>
+<span class="sourceLineNo">1595</span>    @Override<a name="line.1595"></a>
+<span class="sourceLineNo">1596</span>    void init(Cluster cluster) {<a name="line.1596"></a>
+<span class="sourceLineNo">1597</span>      super.init(cluster);<a name="line.1597"></a>
+<span class="sourceLineNo">1598</span>      // max cost is the case where every region replica is hosted together regardless of host<a name="line.1598"></a>
+<span class="sourceLineNo">1599</span>      maxCost = cluster.numHosts &gt; 1 ? getMaxCost(cluster) : 0;<a name="line.1599"></a>
+<span class="sourceLineNo">1600</span>      costsPerGroup = new long[cluster.numHosts];<a name="line.1600"></a>
+<span class="sourceLineNo">1601</span>      primariesOfRegionsPerGroup = cluster.multiServersPerHost // either server based or host based<a name="line.1601"></a>
+<span class="sourceLineNo">1602</span>          ? cluster.primariesOfRegionsPerHost<a name="line.1602"></a>
+<span class="sourceLineNo">1603</span>          : cluster.primariesOfRegionsPerServer;<a name="line.1603"></a>
+<span class="sourceLineNo">1604</span>      for (int i = 0 ; i &lt; primariesOfRegionsPerGroup.length; i++) {<a name="line.1604"></a>
+<span class="sourceLineNo">1605</span>        costsPerGroup[i] = costPerGroup(primariesOfRegionsPerGroup[i]);<a name="line.1605"></a>
+<span class="sourceLineNo">1606</span>      }<a name="line.1606"></a>
+<span class="sourceLineNo">1607</span>    }<a name="line.1607"></a>
+<span class="sourceLineNo">1608</span><a name="line.1608"></a>
+<span class="sourceLineNo">1609</span>    long getMaxCost(Cluster cluster) {<a name="line.1609"></a>
+<span class="sourceLineNo">1610</span>      if (!cluster.hasRegionReplicas) {<a name="line.1610"></a>
+<span class="sourceLineNo">1611</span>        return 0; // short circuit<a name="line.1611"></a>
+<span class="sourceLineNo">1612</span>      }<a name="line.1612"></a>
+<span class="sourceLineNo">1613</span>      // max cost is the case where every region replica is hosted together regardless of host<a name="line.1613"></a>
+<span class="sourceLineNo">1614</span>      int[] primariesOfRegions = new int[cluster.numRegions];<a name="line.1614"></a>
+<span class="sourceLineNo">1615</span>      System.arraycopy(cluster.regionIndexToPrimaryIndex, 0, primariesOfRegions, 0,<a name="line.1615"></a>
+<span class="sourceLineNo">1616</span>          cluster.regions.length);<a name="line.1616"></a>
 <span class="sourceLineNo">1617</span><a name="line.1617"></a>
-<span class="sourceLineNo">1618</span>      // compute numReplicas from the sorted array<a name="line.1618"></a>
-<span class="sourceLineNo">1619</span>      return costPerGroup(primariesOfRegions);<a name="line.1619"></a>
-<span class="sourceLineNo">1620</span>    }<a name="line.1620"></a>
-<span class="sourceLineNo">1621</span><a name="line.1621"></a>
-<span class="sourceLineNo">1622</span>    @Override<a name="line.1622"></a>
-<span class="sourceLineNo">1623</span>    boolean isNeeded() {<a name="line.1623"></a>
-<span class="sourceLineNo">1624</span>      return cluster.hasRegionReplicas;<a name="line.1624"></a>
-<span class="sourceLineNo">1625</span>    }<a name="line.1625"></a>
-<span class="sourceLineNo">1626</span><a name="line.1626"></a>
-<span class="sourceLineNo">1627</span>    @Override<a name="line.1627"></a>
-<span class="sourceLineNo">1628</span>    protected double cost() {<a name="line.1628"></a>
-<span class="sourceLineNo">1629</span>      if (maxCost &lt;= 0) {<a name="line.1629"></a>
-<span class="sourceLineNo">1630</span>        return 0;<a name="line.1630"></a>
-<span class="sourceLineNo">1631</span>      }<a name="line.1631"></a>
-<span class="sourceLineNo">1632</span><a name="line.1632"></a>
-<span class="sourceLineNo">1633</span>      long totalCost = 0;<a name="line.1633"></a>
-<span class="sourceLineNo">1634</span>      for (int i = 0 ; i &lt; costsPerGroup.length; i++) {<a name="line.1634"></a>
-<span class="sourceLineNo">1635</span>        totalCost += costsPerGroup[i];<a name="line.1635"></a>
-<span class="sourceLineNo">1636</span>      }<a name="line.1636"></a>
-<span class="sourceLineNo">1637</span>      return scale(0, maxCost, totalCost);<a name="line.1637"></a>
-<span class="sourceLineNo">1638</span>    }<a name="line.1638"></a>
-<span class="sourceLineNo">1639</span><a name="line.1639"></a>
-<span class="sourceLineNo">1640</span>    /**<a name="line.1640"></a>
-<span class="sourceLineNo">1641</span>     * For each primary region, it computes the total number of replicas in the array (numReplicas)<a name="line.1641"></a>
-<span class="sourceLineNo">1642</span>     * and returns a sum of numReplicas-1 squared. For example, if the server hosts<a name="line.1642"></a>
-<span class="sourceLineNo">1643</span>     * regions a, b, c, d, e, f where a and b are same replicas, and c,d,e are same replicas, it<a name="line.1643"></a>
-<span class="sourceLineNo">1644</span>     * returns (2-1) * (2-1) + (3-1) * (3-1) + (1-1) * (1-1).<a name="line.1644"></a>
-<span class="sourceLineNo">1645</span>     * @param primariesOfRegions a sorted array of primary regions ids for the regions hosted<a name="line.1645"></a>
-<span class="sourceLineNo">1646</span>     * @return a sum of numReplicas-1 squared for each primary region in the group.<a name="line.1646"></a>
-<span class="sourceLineNo">1647</span>     */<a name="line.1647"></a>
-<span class="sourceLineNo">1648</span>    protected long costPerGroup(int[] primariesOfRegions) {<a name="line.1648"></a>
-<span class="sourceLineNo">1649</span>      long cost = 0;<a name="line.1649"></a>
-<span class="sourceLineNo">1650</span>      int currentPrimary = -1;<a name="line.1650"></a>
-<span class="sourceLineNo">1651</span>      int currentPrimaryIndex = -1;<a name="line.1651"></a>
-<span class="sourceLineNo">1652</span>      // primariesOfRegions is a sorted array of primary ids of regions. Replicas of regions<a name="line.1652"></a>
-<span class="sourceLineNo">1653</span>      // sharing the same primary will have consecutive numbers in the array.<a name="line.1653"></a>
-<span class="sourceLineNo">1654</span>      for (int j = 0 ; j &lt;= primariesOfRegions.length; j++) {<a name="line.1654"></a>
-<span class="sourceLineNo">1655</span>        int primary = j &lt; primariesOfRegions.length ? primariesOfRegions[j] : -1;<a name="line.1655"></a>
-<span class="sourceLineNo">1656</span>        if (primary != currentPrimary) { // we see a new primary<a name="line.1656"></a>
-<span class="sourceLineNo">1657</span>          int numReplicas = j - currentPrimaryIndex;<a name="line.1657"></a>
-<span class="sourceLineNo">1658</span>          // square the cost<a name="line.1658"></a>
-<span class="sourceLineNo">1659</span>          if (numReplicas &gt; 1) { // means consecutive primaries, indicating co-location<a name="line.1659"></a>
-<span class="sourceLineNo">1660</span>            cost += (numReplicas - 1) * (numReplicas - 1);<a name="line.1660"></a>
-<span class="sourceLineNo">1661</span>          }<a name="line.1661"></a>
-<span class="sourceLineNo">1662</span>          currentPrimary = primary;<a name="line.1662"></a>
-<span class="sourceLineNo">1663</span>          currentPrimaryIndex = j;<a name="line.1663"></a>
-<span class="sourceLineNo">1664</span>        }<a name="line.1664"></a>
-<span class="sourceLineNo">1665</span>      }<a name="line.1665"></a>
-<span class="sourceLineNo">1666</span><a name="line.1666"></a>
-<span class="sourceLineNo">1667</span>      return cost;<a name="line.1667"></a>
-<span class="sourceLineNo">1668</span>    }<a name="line.1668"></a>
-<span class="sourceLineNo">1669</span><a name="line.1669"></a>
-<span class="sourceLineNo">1670</span>    @Override<a name="line.1670"></a>
-<span class="sourceLineNo">1671</span>    protected void regionMoved(int region, int oldServer, int newServer) {<a name="line.1671"></a>
-<span class="sourceLineNo">1672</span>      if (maxCost &lt;= 0) {<a name="line.1672"></a>
-<span class="sourceLineNo">1673</span>        return; // no need to compute<a name="line.1673"></a>
-<span class="sourceLineNo">1674</span>      }<a name="line.1674"></a>
-<span class="sourceLineNo">1675</span>      if (cluster.multiServersPerHost) {<a name="line.1675"></a>
-<span class="sourceLineNo">1676</span>        int oldHost = cluster.serverIndexToHostIndex[oldServer];<a name="line.1676"></a>
-<span class="sourceLineNo">1677</span>        int newHost = cluster.serverIndexToHostIndex[newServer];<a name="line.1677"></a>
-<span class="sourceLineNo">1678</span>        if (newHost != oldHost) {<a name="line.1678"></a>
-<span class="sourceLineNo">1679</span>          costsPerGroup[oldHost] = costPerGroup(cluster.primariesOfRegionsPerHost[oldHost]);<a name="line.1679"></a>
-<span class="sourceLineNo">1680</span>          costsPerGroup[newHost] = costPerGroup(cluster.primariesOfRegionsPerHost[newHost]);<a name="line.1680"></a>
-<span class="sourceLineNo">1681</span>        }<a name="line.1681"></a>
-<span class="sourceLineNo">1682</span>      } else {<a name="line.1682"></a>
-<span class="sourceLineNo">1683</span>        costsPerGroup[oldServer] = costPerGroup(cluster.primariesOfRegionsPerServer[oldServer]);<a name="line.1683"></a>
-<span class="sourceLineNo">1684</span>        costsPerGroup[newServer] = costPerGroup(cluster.primariesOfRegionsPerServer[newServer]);<a name="line.1684"></a>
-<span class="sourceLineNo">1685</span>      }<a name="line.1685"></a>
-<span class="sourceLineNo">1686</span>    }<a name="line.1686"></a>
-<span class="sourceLineNo">1687</span>  }<a name="line.1687"></a>
-<span class="sourceLineNo">1688</span><a name="line.1688"></a>
-<span class="sourceLineNo">1689</span>  /**<a name="line.1689"></a>
-<span class="sourceLineNo">1690</span>   * A cost function for region replicas for the rack distribution. We give a relatively high<a name="line.1690"></a>
-<span class="sourceLineNo">1691</span>   * cost to hosting replicas of the same region in the same rack. We do not prevent the case<a name="line.1691"></a>
-<span class="sourceLineNo">1692</span>   * though.<a name="line.1692"></a>
-<span class="sourceLineNo">1693</span>   */<a name="line.1693"></a>
-<span class="sourceLineNo">1694</span>  static class RegionReplicaRackCostFunction extends RegionReplicaHostCostFunction {<a name="line.1694"></a>
-<span class="sourceLineNo">1695</span>    private static final String REGION_REPLICA_RACK_COST_KEY =<a name="line.1695"></a>
-<span class="sourceLineNo">1696</span>        "hbase.master.balancer.stochastic.regionReplicaRackCostKey";<a name="line.1696"></a>
-<span class="sourceLineNo">1697</span>    private static final float DEFAULT_REGION_REPLICA_RACK_COST_KEY = 10000;<a name="line.1697"></a>
-<span class="sourceLineNo">1698</span><a name="line.1698"></a>
-<span class="sourceLineNo">1699</span>    public RegionReplicaRackCostFunction(Configuration conf) {<a name="line.1699"></a>
-<span class="sourceLineNo">1700</span>      super(conf);<a name="line.1700"></a>
-<span class="sourceLineNo">1701</span>      this.setMultiplier(conf.getFloat(REGION_REPLICA_RACK_COST_KEY,<a name="line.1701"></a>
-<span class="sourceLineNo">1702</span>        DEFAULT_REGION_REPLICA_RACK_COST_KEY));<a name="line.1702"></a>
-<span class="sourceLineNo">1703</span>    }<a name="line.1703"></a>
-<span class="sourceLineNo">1704</span><a name="line.1704"></a>
-<span class="sourceLineNo">1705</span>    @Override<a name="line.1705"></a>
-<span class="sourceLineNo">1706</span>    void init(Cluster cluster) {<a name="line.1706"></a>
-<span class="sourceLineNo">1707</span>      this.cluster = cluster;<a name="line.1707"></a>
-<span class="sourceLineNo">1708</span>      if (cluster.numRacks &lt;= 1) {<a name="line.1708"></a>
-<span class="sourceLineNo">1709</span>        maxCost = 0;<a name="line.1709"></a>
-<span class="sourceLineNo">1710</span>        return; // disabled for 1 rack<a name="line.1710"></a>
-<span class="sourceLineNo">1711</span>      }<a name="line.1711"></a>
-<span class="sourceLineNo">1712</span>      // max cost is the case where every region replica is hosted together regardless of rack<a name="line.1712"></a>
-<span class="sourceLineNo">1713</span>      maxCost = getMaxCost(cluster);<a name="line.1713"></a>
-<span class="sourceLineNo">1714</span>      costsPerGroup = new long[cluster.numRacks];<a name="line.1714"></a>
-<span class="sourceLineNo">1715</span>      for (int i = 0 ; i &lt; cluster.primariesOfRegionsPerRack.length; i++) {<a name="line.1715"></a>
-<span class="sourceLineNo">1716</span>        costsPerGroup[i] = costPerGroup(cluster.primariesOfRegionsPerRack[i]);<a name="line.1716"></a>
-<span class="sourceLineNo">1717</span>      }<a name="line.1717"></a>
-<span class="sourceLineNo">1718</span>    }<a name="line.1718"></a>
-<span class="sourceLineNo">1719</span><a name="line.1719"></a>
-<span class="sourceLineNo">1720</span>    @Override<a name="line.1720"></a>
-<span class="sourceLineNo">1721</span>    protected void regionMoved(int region, int oldServer, int newServer) {<a name="line.1721"></a>
-<span class="sourceLineNo">1722</span>      if (maxCost &lt;= 0) {<a name="line.1722"></a>
-<span class="sourceLineNo">1723</span>        return; // no need to compute<a name="line.1723"></a>
-<span class="sourceLineNo">1724</span>      }<a name="line.1724"></a>
-<span class="sourceLineNo">1725</span>      int oldRack = cluster.serverIndexToRackIndex[oldServer];<a name="line.1725"></a>
-<span class="sourceLineNo">1726</span>      int newRack = cluster.serverIndexToRackIndex[newServer];<a name="line.1726"></a>
-<span class="sourceLineNo">1727</span>      if (newRack != oldRack) {<a name="line.1727"></a>
-<span class="sourceLineNo">1728</span>        costsPerGroup[oldRack] = costPerGroup(cluster.primariesOfRegionsPerRack[oldRack]);<a name="line.1728"></a>
-<span class="sourceLineNo">1729</span>        costsPerGroup[newRack] = costPerGroup(cluster.primariesOfRegionsPerRack[newRack]);<a name="line.1729"></a>
-<span class="sourceLineNo">1730</span>      }<a name="line.1730"></a>
-<span class="sourceLineNo">1731</span>    }<a name="line.1731"></a>
-<span class="sourceLineNo">1732</span>  }<a name="line.1732"></a>
-<span class="sourceLineNo">1733</span><a name="line.1733"></a>
-<span class="sourceLineNo">1734</span>  /**<a name="line.1734"></a>
-<span class="sourceLineNo">1735</span>   * Compute the cost of total memstore size.  The more unbalanced the higher the<a name="line.1735"></a>
-<span class="sourceLineNo">1736</span>   * computed cost will be.  This uses a rolling average of regionload.<a name="line.1736"></a>
-<span class="sourceLineNo">1737</span>   */<a name="line.1737"></a>
-<span class="sourceLineNo">1738</span>  static class MemStoreSizeCostFunction extends CostFromRegionLoadAsRateFunction {<a name="line.1738"></a>
-<span class="sourceLineNo">1739</span><a name="line.1739"></a>
-<span class="sourceLineNo">1740</span>    private static final String MEMSTORE_SIZE_COST_KEY =<a name="line.1740"></a>
-<span class="sourceLineNo">1741</span>        "hbase.master.balancer.stochastic.memstoreSizeCost";<a name="line.1741"></a>
-<span class="sourceLineNo">1742</span>    private static final float DEFAULT_MEMSTORE_SIZE_COST = 5;<a name="line.1742"></a>
-<span class="sourceLineNo">1743</span><a name="line.1743"></a>
-<span class="sourceLineNo">1744</span>    MemStoreSizeCostFunction(Configuration conf) {<a name="line.1744"></a>
-<span class="sourceLineNo">1745</span>      super(conf);<a name="line.1745"></a>
-<span class="sourceLineNo">1746</span>      this.setMultiplier(conf.getFloat(MEMSTORE_SIZE_COST_KEY, DEFAULT_MEMSTORE_SIZE_COST));<a name="line.1746"></a>
-<span class="sourceLineNo">1747</span>    }<a name="line.1747"></a>
-<span class="sourceLineNo">1748</span><a name="line.1748"></a>
-<span class="sourceLineNo">1749</span>    @Override<a name="line.1749"></a>
-<span class="sourceLineNo">1750</span>    protected double getCostFromRl(BalancerRegionLoad rl) {<a name="line.1750"></a>
-<span class="sourceLineNo">1751</span>      return rl.getMemStoreSizeMB();<a name="line.1751"></a>
-<span class="sourceLineNo">1752</span>    }<a name="line.1752"></a>
-<span class="sourceLineNo">1753</span>  }<a name="line.1753"></a>
-<span class="sourceLineNo">1754</span><a name="line.1754"></a>
-<span class="sourceLineNo">1755</span>  /**<a name="line.1755"></a>
-<span class="sourceLineNo">1756</span>   * Compute the cost of total open storefiles size.  The more unbalanced the higher the<a name="line.1756"></a>
-<span class="sourceLineNo">1757</span>   * computed cost will be.  This uses a rolling average of regionload.<a name="line.1757"></a>
-<span class="sourceLineNo">1758</span>   */<a name="line.1758"></a>
-<span class="sourceLineNo">1759</span>  static class StoreFileCostFunction extends CostFromRegionLoadFunction {<a name="line.1759"></a>
-<span class="sourceLineNo">1760</span><a name="line.1760"></a>
-<span class="sourceLineNo">1761</span>    private static final String STOREFILE_SIZE_COST_KEY =<a name="line.1761"></a>
-<span class="sourceLineNo">1762</span>        "hbase.master.balancer.stochastic.storefileSizeCost";<a name="line.1762"></a>
-<span class="sourceLineNo">1763</span>    private static final float DEFAULT_STOREFILE_SIZE_COST = 5;<a name="line.1763"></a>
-<span class="sourceLineNo">1764</span><a name="line.1764"></a>
-<span class="sourceLineNo">1765</span>    StoreFileCostFunction(Configuration conf) {<a name="line.1765"></a>
-<span class="sourceLineNo">1766</span>      super(conf);<a name="line.1766"></a>
-<span class="sourceLineNo">1767</span>      this.setMultiplier(conf.getFloat(STOREFILE_SIZE_COST_KEY, DEFAULT_STOREFILE_SIZE_COST));<a name="line.1767"></a>
-<span class="sourceLineNo">1768</span>    }<a name="line.1768"></a>
-<span class="sourceLineNo">1769</span><a name="line.1769"></a>
-<span class="sourceLineNo">1770</span>    @Override<a name="line.1770"></a>
-<span class="sourceLineNo">1771</span>    protected double getCostFromRl(BalancerRegionLoad rl) {<a name="line.1771"></a>
-<span class="sourceLineNo">1772</span>      return rl.getStorefileSizeMB();<a name="line.1772"></a>
-<span class="sourceLineNo">1773</span>    }<a name="line.1773"></a>
-<span class="sourceLineNo">1774</span>  }<a name="line.1774"></a>
-<span class="sourceLineNo">1775</span><a name="line.1775"></a>
-<span class="sourceLineNo">1776</span>  /**<a name="line.1776"></a>
-<span class="sourceLineNo">1777</span>   * A helper function to compose the attribute name from tablename and costfunction name<a name="line.1777"></a>
-<span class="sourceLineNo">1778</span>   */<a name="line.1778"></a>
-<span class="sourceLineNo">1779</span>  public static String composeAttributeName(String tableName, String costFunctionName) {<a name="line.1779"></a>
-<span class="sourceLineNo">1780</span>    return tableName + TABLE_FUNCTION_SEP + costFunctionName;<a name="line.1780"></a>
-<span class="sourceLineNo">1781</span>  }<a name="line.1781"></a>
-<span class="sourceLineNo">1782</span>}<a name="line.1782"></a>
+<span class="sourceLineNo">1618</span>      Arrays.sort(primariesOfRegions);<a name="line.1618"></a>
+<span class="sourceLineNo">1619</span><a name="line.1619"></a>
+<span class="sourceLineNo">1620</span>      // compute numReplicas from the sorted array<a name="line.1620"></a>
+<span class="sourceLineNo">1621</span>      return costPerGroup(primariesOfRegions);<a name="line.1621"></a>
+<span class="sourceLineNo">1622</span>    }<a name="line.1622"></a>
+<span class="sourceLineNo">1623</span><a name="line.1623"></a>
+<span class="sourceLineNo">1624</span>    @Override<a name="line.1624"></a>
+<span class="sourceLineNo">1625</span>    boolean isNeeded() {<a name="line.1625"></a>
+<span class="sourceLineNo">1626</span>      return cluster.hasRegionReplicas;<a name="line.1626"></a>
+<span class="sourceLineNo">1627</span>    }<a name="line.1627"></a>
+<span class="sourceLineNo">1628</span><a name="line.1628"></a>
+<span class="sourceLineNo">1629</span>    @Override<a name="line.1629"></a>
+<span class="sourceLineNo">1630</span>    protected double cost() {<a name="line.1630"></a>
+<span class="sourceLineNo">1631</span>      if (maxCost &lt;= 0) {<a name="line.1631"></a>
+<span class="sourceLineNo">1632</span>        return 0;<a name="line.1632"></a>
+<span class="sourceLineNo">1633</span>      }<a name="line.1633"></a>
+<span class="sourceLineNo">1634</span><a name="line.1634"></a>
+<span class="sourceLineNo">1635</span>      long totalCost = 0;<a name="line.1635"></a>
+<span class="sourceLineNo">1636</span>      for (int i = 0 ; i &lt; costsPerGroup.length; i++) {<a name="line.1636"></a>
+<span class="sourceLineNo">1637</span>        totalCost += costsPerGroup[i];<a name="line.1637"></a>
+<span class="sourceLineNo">1638</span>      }<a name="line.1638"></a>
+<span class="sourceLineNo">1639</span>      return scale(0, maxCost, totalCost);<a name="line.1639"></a>
+<span class="sourceLineNo">1640</span>    }<a name="line.1640"></a>
+<span class="sourceLineNo">1641</span><a name="line.1641"></a>
+<span class="sourceLineNo">1642</span>    /**<a name="line.1642"></a>
+<span class="sourceLineNo">1643</span>     * For each primary region, it computes the total number of replicas in the array (numReplicas)<a name="line.1643"></a>
+<span class="sourceLineNo">1644</span>     * and returns a sum of numReplicas-1 squared. For example, if the server hosts<a name="line.1644"></a>
+<span class="sourceLineNo">1645</span>     * regions a, b, c, d, e, f where a and b are same replicas, and c,d,e are same replicas, it<a name="line.1645"></a>
+<span class="sourceLineNo">1646</span>     * returns (2-1) * (2-1) + (3-1) * (3-1) + (1-1) * (1-1).<a name="line.1646"></a>
+<span class="sourceLineNo">1647</span>     * @param primariesOfRegions a sorted array of primary regions ids for the regions hosted<a name="line.1647"></a>
+<span class="sourceLineNo">1648</span>     * @return a sum of numReplicas-1 squared for each primary region in the group.<a name="line.1648"></a>
+<span class="sourceLineNo">1649</span>     */<a name="line.1649"></a>
+<span class="sourceLineNo">1650</span>    protected long costPerGroup(int[] primariesOfRegions) {<a name="line.1650"></a>
+<span class="sourceLineNo">1651</span>      long cost = 0;<a name="line.1651"></a>
+<span class="sourceLineNo">1652</span>      int currentPrimary = -1;<a name="line.1652"></a>
+<span class="sourceLineNo">1653</span>      int currentPrimaryIndex = -1;<a name="line.1653"></a>
+<span class="sourceLineNo">1654</span>      // primariesOfRegions is a sorted array of primary ids of regions. Replicas of regions<a name="line.1654"></a>
+<span class="sourceLineNo">1655</span>      // sharing the same primary will have consecutive numbers in the array.<a name="line.1655"></a>
+<span class="sourceLineNo">1656</span>      for (int j = 0 ; j &lt;= primariesOfRegions.length; j++) {<a name="line.1656"></a>
+<span class="sourceLineNo">1657</span>        int primary = j &lt; primariesOfRegions.length ? primariesOfRegions[j] : -1;<a name="line.1657"></a>
+<span class="sourceLineNo">1658</span>        if (primary != currentPrimary) { // we see a new primary<a name="line.1658"></a>
+<span class="sourceLineNo">1659</span>          int numReplicas = j - currentPrimaryIndex;<a name="line.1659"></a>
+<span class="sourceLineNo">1660</span>          // square the cost<a name="line.1660"></a>
+<span class="sourceLineNo">1661</span>          if (numReplicas &gt; 1) { // means consecutive primaries, indicating co-location<a name="line.1661"></a>
+<span class="sourceLineNo">1662</span>            cost += (numReplicas - 1) * (numReplicas - 1);<a name="line.1662"></a>
+<span class="sourceLineNo">1663</span>          }<a name="line.1663"></a>
+<span class="sourceLineNo">1664</span>          currentPrimary = primary;<a name="line.1664"></a>
+<span class="sourceLineNo">1665</span>          currentPrimaryIndex = j;<a name="line.1665"></a>
+<span class="sourceLineNo">1666</span>        }<a name="line.1666"></a>
+<span class="sourceLineNo">1667</span>      }<a name="line.1667"></a>
+<span class="sourceLineNo">1668</span><a name="line.1668"></a>
+<span class="sourceLineNo">1669</span>      return cost;<a name="line.1669"></a>
+<span class="sourceLineNo">1670</span>    }<a name="line.1670"></a>
+<span class="sourceLineNo">1671</span><a name="line.1671"></a>
+<span class="sourceLineNo">1672</span>    @Override<a name="line.1672"></a>
+<span class="sourceLineNo">1673</span>    protected void regionMoved(int region, int oldServer, int newServer) {<a name="line.1673"></a>
+<span class="sourceLineNo">1674</span>      if (maxCost &lt;= 0) {<a name="line.1674"></a>
+<span class="sourceLineNo">1675</span>        return; // no need to compute<a name="line.1675"></a>
+<span class="sourceLineNo">1676</span>      }<a name="line.1676"></a>
+<span class="sourceLineNo">1677</span>      if (cluster.multiServersPerHost) {<a name="line.1677"></a>
+<span class="sourceLineNo">1678</span>        int oldHost = cluster.serverIndexToHostIndex[oldServer];<a name="line.1678"></a>
+<span class="sourceLineNo">1679</span>        int newHost = cluster.serverIndexToHostIndex[newServer];<a name="line.1679"></a>
+<span class="sourceLineNo">1680</span>        if (newHost != oldHost) {<a name="line.1680"></a>
+<span class="sourceLineNo">1681</span>          costsPerGroup[oldHost] = costPerGroup(cluster.primariesOfRegionsPerHost[oldHost]);<a name="line.1681"></a>
+<span class="sourceLineNo">1682</span>          costsPerGroup[newHost] = costPerGroup(cluster.primariesOfRegionsPerHost[newHost]);<a name="line.1682"></a>
+<span class="sourceLineNo">1683</span>        }<a name="line.1683"></a>
+<span class="sourceLineNo">1684</span>      } else {<a name="line.1684"></a>
+<span class="sourceLineNo">1685</span>        costsPerGroup[oldServer] = costPerGroup(cluster.primariesOfRegionsPerServer[oldServer]);<a name="line.1685"></a>
+<span class="sourceLineNo">1686</span>        costsPerGroup[newServer] = costPerGroup(cluster.primariesOfRegionsPerServer[newServer]);<a name="line.1686"></a>
+<span class="sourceLineNo">1687</span>      }<a name="line.1687"></a>
+<span class="sourceLineNo">1688</span>    }<a name="line.1688"></a>
+<span class="sourceLineNo">1689</span>  }<a name="line.1689"></a>
+<span class="sourceLineNo">1690</span><a name="line.1690"></a>
+<span class="sourceLineNo">1691</span>  /**<a name="line.1691"></a>
+<span class="sourceLineNo">1692</span>   * A cost function for region replicas for the rack distribution. We give a relatively high<a name="line.1692"></a>
+<span class="sourceLineNo">1693</span>   * cost to hosting replicas of the same region in the same rack. We do not prevent the case<a name="line.1693"></a>
+<span class="sourceLineNo">1694</span>   * though.<a name="line.1694"></a>
+<span class="sourceLineNo">1695</span>   */<a name="line.1695"></a>
+<span class="sourceLineNo">1696</span>  static class RegionReplicaRackCostFunction extends RegionReplicaHostCostFunction {<a name="line.1696"></a>
+<span class="sourceLineNo">1697</span>    private static final String REGION_REPLICA_RACK_COST_KEY =<a name="line.1697"></a>
+<span class="sourceLineNo">1698</span>        "hbase.master.balancer.stochastic.regionReplicaRackCostKey";<a name="line.1698"></a>
+<span class="sourceLineNo">1699</span>    private static final float DEFAULT_REGION_REPLICA_RACK_COST_KEY = 10000;<a name="line.1699"></a>
+<span class="sourceLineNo">1700</span><a name="line.1700"></a>
+<span class="sourceLineNo">1701</span>    public RegionReplicaRackCostFunction(Configuration conf) {<a name="line.1701"></a>
+<span class="sourceLineNo">1702</span>      super(conf);<a name="line.1702"></a>
+<span class="sourceLineNo">1703</span>      this.setMultiplier(conf.getFloat(REGION_REPLICA_RACK_COST_KEY,<a name="line.1703"></a>
+<span class="sourceLineNo">1704</span>        DEFAULT_REGION_REPLICA_RACK_COST_KEY));<a name="line.1704"></a>
+<span class="sourceLineNo">1705</span>    }<a name="line.1705"></a>
+<span class="sourceLineNo">1706</span><a name="line.1706"></a>
+<span class="sourceLineNo">1707</span>    @Override<a name="line.1707"></a>
+<span class="sourceLineNo">1708</span>    void init(Cluster cluster) {<a name="line.1708"></a>
+<span class="sourceLineNo">1709</span>      this.cluster = cluster;<a name="line.1709"></a>
+<span class="sourceLineNo">1710</span>      if (cluster.numRacks &lt;= 1) {<a name="line.1710"></a>
+<span class="sourceLineNo">1711</span>        maxCost = 0;<a name="line.1711"></a>
+<span class="sourceLineNo">1712</span>        return; // disabled for 1 rack<a name="line.1712"></a>
+<span class="sourceLineNo">1713</span>      }<a name="line.1713"></a>
+<span class="sourceLineNo">1714</span>      // max cost is the case where every region replica is hosted together regardless of rack<a name="line.1714"></a>
+<span class="sourceLineNo">1715</span>      maxCost = getMaxCost(cluster);<a name="line.1715"></a>
+<span class="sourceLineNo">1716</span>      costsPerGroup = new long[cluster.numRacks];<a name="line.1716"></a>
+<span class="sourceLineNo">1717</span>      for (int i = 0 ; i &lt; cluster.primariesOfRegionsPerRack.length; i++) {<a name="line.1717"></a>
+<span class="sourceLineNo">1718</span>        costsPerGroup[i] = costPerGroup(cluster.primariesOfRegionsPerRack[i]);<a name="line.1718"></a>
+<span class="sourceLineNo">1719</span>      }<a name="line.1719"></a>
+<span class="sourceLineNo">1720</span>    }<a name="line.1720"></a>
+<span class="sourceLineNo">1721</span><a name="line.1721"></a>
+<span class="sourceLineNo">1722</span>    @Override<a name="line.1722"></a>
+<span class="sourceLineNo">1723</span>    protected void regionMoved(int region, int oldServer, int newServer) {<a name="line.1723"></a>
+<span class="sourceLineNo">1724</span>      if (maxCost &lt;= 0) {<a name="line.1724"></a>
+<span class="sourceLineNo">1725</span>        return; // no need to compute<a name="line.1725"></a>
+<span class="sourceLineNo">1726</span>      }<a name="line.1726"></a>
+<span class="sourceLineNo">1727</span>      int oldRack = cluster.serverIndexToRackIndex[oldServer];<a name="line.1727"></a>
+<span class="sourceLineNo">1728</span>      int newRack = cluster.serverIndexToRackIndex[newServer];<a name="line.1728"></a>
+<span class="sourceLineNo">1729</span>      if (newRack != oldRack) {<a name="line.1729"></a>
+<span class="sourceLineNo">1730</span>        costsPerGroup[oldRack] = costPerGroup(cluster.primariesOfRegionsPerRack[oldRack]);<a name="line.1730"></a>
+<span class="sourceLineNo">1731</span>        costsPerGroup[newRack] = costPerGroup(cluster.primariesOfRegionsPerRack[newRack]);<a name="line.1731"></a>
+<span class="sourceLineNo">1732</span>      }<a name="line.1732"></a>
+<span class="sourceLineNo">1733</span>    }<a name="line.1733"></a>
+<span class="sourceLineNo">1734</span>  }<a name="line.1734"></a>
+<span class="sourceLineNo">1735</span><a name="line.1735"></a>
+<span class="sourceLineNo">1736</span>  /**<a name="line.1736"></a>
+<span class="sourceLineNo">1737</span>   * Compute the cost of total memstore size.  The more unbalanced the higher the<a name="line.1737"></a>
+<span class="sourceLineNo">1738</span>   * computed cost will be.  This uses a rolling average of regionload.<a name="line.1738"></a>
+<span class="sourceLineNo">1739</span>   */<a name="line.1739"></a>
+<span class="sourceLineNo">1740</span>  static class MemStoreSizeCostFunction extends CostFromRegionLoadAsRateFunction {<a name="line.1740"></a>
+<span class="sourceLineNo">1741</span><a name="line.1741"></a>
+<span class="sourceLineNo">1742</span>    private static final String MEMSTORE_SIZE_COST_KEY =<a name="line.1742"></a>
+<span class="sourceLineNo">1743</span>        "hbase.master.balancer.stochastic.memstoreSizeCost";<a name="line.1743"></a>
+<span class="sourceLineNo">1744</span>    private static final float DEFAULT_MEMSTORE_SIZE_COST = 5;<a name="line.1744"></a>
+<span class="sourceLineNo">1745</span><a name="line.1745"></a>
+<span class="sourceLineNo">1746</span>    MemStoreSizeCostFunction(Configuration conf) {<a name="line.1746"></a>
+<span class="sourceLineNo">1747</span>      super(conf);<a name="line.1747"></a>
+<span class="sourceLineNo">1748</span>      this.setMultiplier(conf.getFloat(MEMSTORE_SIZE_COST_KEY, DEFAULT_MEMSTORE_SIZE_COST));<a name="line.1748"></a>
+<span class="sourceLineNo">1749</span>    }<a name="line.1749"></a>
+<span class="sourceLineNo">1750</span><a name="line.1750"></a>
+<span class="sourceLineNo">1751</span>    @Override<a name="line.1751"></a>
+<span class="sourceLineNo">1752</span>    protected double getCostFromRl(BalancerRegionLoad rl) {<a name="line.1752"></a>
+<span class="sourceLineNo">1753</span>      return rl.getMemStoreSizeMB();<a name="line.1753"></a>
+<span class="sourceLineNo">1754</span>    }<a name="line.1754"></a>
+<span class="sourceLineNo">1755</span>  }<a name="line.1755"></a>
+<span class="sourceLineNo">1756</span><a name="line.1756"></a>
+<span class="sourceLineNo">1757</span>  /**<a name="line.1757"></a>
+<span class="sourceLineNo">1758</span>   * Compute the cost of total open storefiles size.  The more unbalanced the higher the<a name="line.1758"></a>
+<span class="sourceLineNo">1759</span>   * computed cost will be.  This uses a rolling average of regionload.<a name="line.1759"></a>
+<span class="sourceLineNo">1760</span>   */<a name="line.1760"></a>
+<span class="sourceLineNo">1761</span>  static class StoreFileCostFunction extends CostFromRegionLoadFunction {<a name="line.1761"></a>
+<span class="sourceLineNo">1762</span><a name="line.1762"></a>
+<span class="sourceLineNo">1763</span>    private static final String STOREFILE_SIZE_COST_KEY =<a name="line.1763"></a>
+<span class="sourceLineNo">1764</span>        "hbase.master.balancer.stochastic.storefileSizeCost";<a name="line.1764"></a>
+<span class="sourceLineNo">1765</span>    private static final float DEFAULT_STOREFILE_SIZE_COST = 5;<a name="line.1765"></a>
+<span class="sourceLineNo">1766</span><a name="line.1766"></a>
+<span class="sourceLineNo">1767</span>    StoreFileCostFunction(Configuration conf) {<a name="line.1767"></a>
+<span class="sourceLineNo">1768</span>      super(conf);<a name="line.1768"></a>
+<span class="sourceLineNo">1769</span>      this.setMultiplier(conf.getFloat(STOREFILE_SIZE_COST_KEY, DEFAULT_STOREFILE_SIZE_COST));<a name="line.1769"></a>
+<span class="sourceLineNo">1770</span>    }<a name="line.1770"></a>
+<span class="sourceLineNo">1771</span><a name="line.1771"></a>
+<span class="sourceLineNo">1772</span>    @Override<a name="line.1772"></a>
+<span class="sourceLineNo">1773</span>    protected double getCostFromRl(BalancerRegionLoad rl) {<a name="line.1773"></a>
+<span class="sourceLineNo">1774</span>      return rl.getStorefileSizeMB();<a name="line.1774"></a>
+<span class="sourceLineNo">1775</span>    }<a name="line.1775"></a>
+<span class="sourceLineNo">1776</span>  }<a name="line.1776"></a>
+<span class="sourceLineNo">1777</span><a name="line.1777"></a>
+<span class="sourceLineNo">1778</span>  /**<a name="line.1778"></a>
+<span class="sourceLineNo">1779</span>   * A helper function to compose the attribute name from tablename and costfunction name<a name="line.1779"></a>
+<span class="sourceLineNo">1780</span>   */<a name="line.1780"></a>
+<span class="sourceLineNo">1781</span>  public static String composeAttributeName(String tableName, String costFunctionName) {<a name="line.1781"></a>
+<span class="sourceLineNo">1782</span>    return tableName + TABLE_FUNCTION_SEP + costFunctionName;<a name="line.1782"></a>
+<span class="sourceLineNo">1783</span>  }<a name="line.1783"></a>
+<span class="sourceLineNo">1784</span>}<a name="line.1784"></a>
 
 
 
diff --git a/devapidocs/src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CandidateGenerator.html b/devapidocs/src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CandidateGenerator.html
index 4a9d7eb..7ce29c3 100644
--- a/devapidocs/src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CandidateGenerator.html
+++ b/devapidocs/src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CandidateGenerator.html
@@ -356,1438 +356,1440 @@
 <span class="sourceLineNo">348</span>    if (total &lt;= 0 || sumMultiplier &lt;= 0<a name="line.348"></a>
 <span class="sourceLineNo">349</span>        || (sumMultiplier &gt; 0 &amp;&amp; (total / sumMultiplier) &lt; minCostNeedBalance)) {<a name="line.349"></a>
 <span class="sourceLineNo">350</span>      if (LOG.isTraceEnabled()) {<a name="line.350"></a>
-<span class="sourceLineNo">351</span>        LOG.trace("Skipping load balancing because balanced cluster; " + "total cost is " + total<a name="line.351"></a>
-<span class="sourceLineNo">352</span>          + ", sum multiplier is " + sumMultiplier + " min cost which need balance is "<a name="line.352"></a>
-<span class="sourceLineNo">353</span>          + minCostNeedBalance);<a name="line.353"></a>
-<span class="sourceLineNo">354</span>      }<a name="line.354"></a>
-<span class="sourceLineNo">355</span>      return false;<a name="line.355"></a>
-<span class="sourceLineNo">356</span>    }<a name="line.356"></a>
-<span class="sourceLineNo">357</span>    return true;<a name="line.357"></a>
-<span class="sourceLineNo">358</span>  }<a name="line.358"></a>
-<span class="sourceLineNo">359</span><a name="line.359"></a>
-<span class="sourceLineNo">360</span>  @Override<a name="line.360"></a>
-<span class="sourceLineNo">361</span>  public synchronized List&lt;RegionPlan&gt; balanceCluster(TableName tableName, Map&lt;ServerName,<a name="line.361"></a>
-<span class="sourceLineNo">362</span>    List&lt;RegionInfo&gt;&gt; clusterState) {<a name="line.362"></a>
-<span class="sourceLineNo">363</span>    this.tableName = tableName;<a name="line.363"></a>
-<span class="sourceLineNo">364</span>    return balanceCluster(clusterState);<a name="line.364"></a>
-<span class="sourceLineNo">365</span>  }<a name="line.365"></a>
-<span class="sourceLineNo">366</span><a name="line.366"></a>
-<span class="sourceLineNo">367</span>  @VisibleForTesting<a name="line.367"></a>
-<span class="sourceLineNo">368</span>  Cluster.Action nextAction(Cluster cluster) {<a name="line.368"></a>
-<span class="sourceLineNo">369</span>    return candidateGenerators.get(RANDOM.nextInt(candidateGenerators.size()))<a name="line.369"></a>
-<span class="sourceLineNo">370</span>            .generate(cluster);<a name="line.370"></a>
-<span class="sourceLineNo">371</span>  }<a name="line.371"></a>
-<span class="sourceLineNo">372</span><a name="line.372"></a>
-<span class="sourceLineNo">373</span>  /**<a name="line.373"></a>
-<span class="sourceLineNo">374</span>   * Given the cluster state this will try and approach an optimal balance. This<a name="line.374"></a>
-<span class="sourceLineNo">375</span>   * should always approach the optimal state given enough steps.<a name="line.375"></a>
-<span class="sourceLineNo">376</span>   */<a name="line.376"></a>
-<span class="sourceLineNo">377</span>  @Override<a name="line.377"></a>
-<span class="sourceLineNo">378</span>  public synchronized List&lt;RegionPlan&gt; balanceCluster(Map&lt;ServerName,<a name="line.378"></a>
-<span class="sourceLineNo">379</span>    List&lt;RegionInfo&gt;&gt; clusterState) {<a name="line.379"></a>
-<span class="sourceLineNo">380</span>    List&lt;RegionPlan&gt; plans = balanceMasterRegions(clusterState);<a name="line.380"></a>
-<span class="sourceLineNo">381</span>    if (plans != null || clusterState == null || clusterState.size() &lt;= 1) {<a name="line.381"></a>
-<span class="sourceLineNo">382</span>      return plans;<a name="line.382"></a>
-<span class="sourceLineNo">383</span>    }<a name="line.383"></a>
-<span class="sourceLineNo">384</span><a name="line.384"></a>
-<span class="sourceLineNo">385</span>    if (masterServerName != null &amp;&amp; clusterState.containsKey(masterServerName)) {<a name="line.385"></a>
-<span class="sourceLineNo">386</span>      if (clusterState.size() &lt;= 2) {<a name="line.386"></a>
-<span class="sourceLineNo">387</span>        return null;<a name="line.387"></a>
-<span class="sourceLineNo">388</span>      }<a name="line.388"></a>
-<span class="sourceLineNo">389</span>      clusterState = new HashMap&lt;&gt;(clusterState);<a name="line.389"></a>
-<span class="sourceLineNo">390</span>      clusterState.remove(masterServerName);<a name="line.390"></a>
-<span class="sourceLineNo">391</span>    }<a name="line.391"></a>
-<span class="sourceLineNo">392</span><a name="line.392"></a>
-<span class="sourceLineNo">393</span>    // On clusters with lots of HFileLinks or lots of reference files,<a name="line.393"></a>
-<span class="sourceLineNo">394</span>    // instantiating the storefile infos can be quite expensive.<a name="line.394"></a>
-<span class="sourceLineNo">395</span>    // Allow turning this feature off if the locality cost is not going to<a name="line.395"></a>
-<span class="sourceLineNo">396</span>    // be used in any computations.<a name="line.396"></a>
-<span class="sourceLineNo">397</span>    RegionLocationFinder finder = null;<a name="line.397"></a>
-<span class="sourceLineNo">398</span>    if ((this.localityCost != null &amp;&amp; this.localityCost.getMultiplier() &gt; 0)<a name="line.398"></a>
-<span class="sourceLineNo">399</span>        || (this.rackLocalityCost != null &amp;&amp; this.rackLocalityCost.getMultiplier() &gt; 0)) {<a name="line.399"></a>
-<span class="sourceLineNo">400</span>      finder = this.regionFinder;<a name="line.400"></a>
-<span class="sourceLineNo">401</span>    }<a name="line.401"></a>
-<span class="sourceLineNo">402</span><a name="line.402"></a>
-<span class="sourceLineNo">403</span>    //The clusterState that is given to this method contains the state<a name="line.403"></a>
-<span class="sourceLineNo">404</span>    //of all the regions in the table(s) (that's true today)<a name="line.404"></a>
-<span class="sourceLineNo">405</span>    // Keep track of servers to iterate through them.<a name="line.405"></a>
-<span class="sourceLineNo">406</span>    Cluster cluster = new Cluster(clusterState, loads, finder, rackManager);<a name="line.406"></a>
-<span class="sourceLineNo">407</span><a name="line.407"></a>
-<span class="sourceLineNo">408</span>    long startTime = EnvironmentEdgeManager.currentTime();<a name="line.408"></a>
+<span class="sourceLineNo">351</span>        final String loadBalanceTarget =<a name="line.351"></a>
+<span class="sourceLineNo">352</span>            isByTable ? String.format("table (%s)", tableName) : "cluster";<a name="line.352"></a>
+<span class="sourceLineNo">353</span>        LOG.trace("Skipping load balancing because the {} is balanced. Total cost: {}, "<a name="line.353"></a>
+<span class="sourceLineNo">354</span>            + "Sum multiplier: {}, Minimum cost needed for balance: {}", loadBalanceTarget, total,<a name="line.354"></a>
+<span class="sourceLineNo">355</span>            sumMultiplier, minCostNeedBalance);<a name="line.355"></a>
+<span class="sourceLineNo">356</span>      }<a name="line.356"></a>
+<span class="sourceLineNo">357</span>      return false;<a name="line.357"></a>
+<span class="sourceLineNo">358</span>    }<a name="line.358"></a>
+<span class="sourceLineNo">359</span>    return true;<a name="line.359"></a>
+<span class="sourceLineNo">360</span>  }<a name="line.360"></a>
+<span class="sourceLineNo">361</span><a name="line.361"></a>
+<span class="sourceLineNo">362</span>  @Override<a name="line.362"></a>
+<span class="sourceLineNo">363</span>  public synchronized List&lt;RegionPlan&gt; balanceCluster(TableName tableName, Map&lt;ServerName,<a name="line.363"></a>
+<span class="sourceLineNo">364</span>    List&lt;RegionInfo&gt;&gt; clusterState) {<a name="line.364"></a>
+<span class="sourceLineNo">365</span>    this.tableName = tableName;<a name="line.365"></a>
+<span class="sourceLineNo">366</span>    return balanceCluster(clusterState);<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>  @VisibleForTesting<a name="line.369"></a>
+<span class="sourceLineNo">370</span>  Cluster.Action nextAction(Cluster cluster) {<a name="line.370"></a>
+<span class="sourceLineNo">371</span>    return candidateGenerators.get(RANDOM.nextInt(candidateGenerators.size()))<a name="line.371"></a>
+<span class="sourceLineNo">372</span>            .generate(cluster);<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>  /**<a name="line.375"></a>
+<span class="sourceLineNo">376</span>   * Given the cluster state this will try and approach an optimal balance. This<a name="line.376"></a>
+<span class="sourceLineNo">377</span>   * should always approach the optimal state given enough steps.<a name="line.377"></a>
+<span class="sourceLineNo">378</span>   */<a name="line.378"></a>
+<span class="sourceLineNo">379</span>  @Override<a name="line.379"></a>
+<span class="sourceLineNo">380</span>  public synchronized List&lt;RegionPlan&gt; balanceCluster(Map&lt;ServerName,<a name="line.380"></a>
+<span class="sourceLineNo">381</span>    List&lt;RegionInfo&gt;&gt; clusterState) {<a name="line.381"></a>
+<span class="sourceLineNo">382</span>    List&lt;RegionPlan&gt; plans = balanceMasterRegions(clusterState);<a name="line.382"></a>
+<span class="sourceLineNo">383</span>    if (plans != null || clusterState == null || clusterState.size() &lt;= 1) {<a name="line.383"></a>
+<span class="sourceLineNo">384</span>      return plans;<a name="line.384"></a>
+<span class="sourceLineNo">385</span>    }<a name="line.385"></a>
+<span class="sourceLineNo">386</span><a name="line.386"></a>
+<span class="sourceLineNo">387</span>    if (masterServerName != null &amp;&amp; clusterState.containsKey(masterServerName)) {<a name="line.387"></a>
+<span class="sourceLineNo">388</span>      if (clusterState.size() &lt;= 2) {<a name="line.388"></a>
+<span class="sourceLineNo">389</span>        return null;<a name="line.389"></a>
+<span class="sourceLineNo">390</span>      }<a name="line.390"></a>
+<span class="sourceLineNo">391</span>      clusterState = new HashMap&lt;&gt;(clusterState);<a name="line.391"></a>
+<span class="sourceLineNo">392</span>      clusterState.remove(masterServerName);<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>    // On clusters with lots of HFileLinks or lots of reference files,<a name="line.395"></a>
+<span class="sourceLineNo">396</span>    // instantiating the storefile infos can be quite expensive.<a name="line.396"></a>
+<span class="sourceLineNo">397</span>    // Allow turning this feature off if the locality cost is not going to<a name="line.397"></a>
+<span class="sourceLineNo">398</span>    // be used in any computations.<a name="line.398"></a>
+<span class="sourceLineNo">399</span>    RegionLocationFinder finder = null;<a name="line.399"></a>
+<span class="sourceLineNo">400</span>    if ((this.localityCost != null &amp;&amp; this.localityCost.getMultiplier() &gt; 0)<a name="line.400"></a>
+<span class="sourceLineNo">401</span>        || (this.rackLocalityCost != null &amp;&amp; this.rackLocalityCost.getMultiplier() &gt; 0)) {<a name="line.401"></a>
+<span class="sourceLineNo">402</span>      finder = this.regionFinder;<a name="line.402"></a>
+<span class="sourceLineNo">403</span>    }<a name="line.403"></a>
+<span class="sourceLineNo">404</span><a name="line.404"></a>
+<span class="sourceLineNo">405</span>    //The clusterState that is given to this method contains the state<a name="line.405"></a>
+<span class="sourceLineNo">406</span>    //of all the regions in the table(s) (that's true today)<a name="line.406"></a>
+<span class="sourceLineNo">407</span>    // Keep track of servers to iterate through them.<a name="line.407"></a>
+<span class="sourceLineNo">408</span>    Cluster cluster = new Cluster(clusterState, loads, finder, rackManager);<a name="line.408"></a>
 <span class="sourceLineNo">409</span><a name="line.409"></a>
-<span class="sourceLineNo">410</span>    initCosts(cluster);<a name="line.410"></a>
+<span class="sourceLineNo">410</span>    long startTime = EnvironmentEdgeManager.currentTime();<a name="line.410"></a>
 <span class="sourceLineNo">411</span><a name="line.411"></a>
-<span class="sourceLineNo">412</span>    if (!needsBalance(cluster)) {<a name="line.412"></a>
-<span class="sourceLineNo">413</span>      return null;<a name="line.413"></a>
-<span class="sourceLineNo">414</span>    }<a name="line.414"></a>
-<span class="sourceLineNo">415</span><a name="line.415"></a>
-<span class="sourceLineNo">416</span>    double currentCost = computeCost(cluster, Double.MAX_VALUE);<a name="line.416"></a>
-<span class="sourceLineNo">417</span>    curOverallCost = currentCost;<a name="line.417"></a>
-<span class="sourceLineNo">418</span>    for (int i = 0; i &lt; this.curFunctionCosts.length; i++) {<a name="line.418"></a>
-<span class="sourceLineNo">419</span>      curFunctionCosts[i] = tempFunctionCosts[i];<a name="line.419"></a>
-<span class="sourceLineNo">420</span>    }<a name="line.420"></a>
-<span class="sourceLineNo">421</span>    double initCost = currentCost;<a name="line.421"></a>
-<span class="sourceLineNo">422</span>    double newCost = currentCost;<a name="line.422"></a>
-<span class="sourceLineNo">423</span><a name="line.423"></a>
-<span class="sourceLineNo">424</span>    long computedMaxSteps;<a name="line.424"></a>
-<span class="sourceLineNo">425</span>    if (runMaxSteps) {<a name="line.425"></a>
-<span class="sourceLineNo">426</span>      computedMaxSteps = Math.max(this.maxSteps,<a name="line.426"></a>
-<span class="sourceLineNo">427</span>          ((long)cluster.numRegions * (long)this.stepsPerRegion * (long)cluster.numServers));<a name="line.427"></a>
-<span class="sourceLineNo">428</span>    } else {<a name="line.428"></a>
-<span class="sourceLineNo">429</span>      long calculatedMaxSteps = (long)cluster.numRegions * (long)this.stepsPerRegion *<a name="line.429"></a>
-<span class="sourceLineNo">430</span>          (long)cluster.numServers;<a name="line.430"></a>
-<span class="sourceLineNo">431</span>      computedMaxSteps = Math.min(this.maxSteps, calculatedMaxSteps);<a name="line.431"></a>
-<span class="sourceLineNo">432</span>      if (calculatedMaxSteps &gt; maxSteps) {<a name="line.432"></a>
-<span class="sourceLineNo">433</span>        LOG.warn("calculatedMaxSteps:{} for loadbalancer's stochastic walk is larger than "<a name="line.433"></a>
-<span class="sourceLineNo">434</span>            + "maxSteps:{}. Hence load balancing may not work well. Setting parameter "<a name="line.434"></a>
-<span class="sourceLineNo">435</span>            + "\"hbase.master.balancer.stochastic.runMaxSteps\" to true can overcome this issue."<a name="line.435"></a>
-<span class="sourceLineNo">436</span>            + "(This config change does not require service restart)", calculatedMaxSteps,<a name="line.436"></a>
-<span class="sourceLineNo">437</span>            maxSteps);<a name="line.437"></a>
-<span class="sourceLineNo">438</span>      }<a name="line.438"></a>
-<span class="sourceLineNo">439</span>    }<a name="line.439"></a>
-<span class="sourceLineNo">440</span>    LOG.info("start StochasticLoadBalancer.balancer, initCost=" + currentCost + ", functionCost="<a name="line.440"></a>
-<span class="sourceLineNo">441</span>        + functionCost() + " computedMaxSteps: " + computedMaxSteps);<a name="line.441"></a>
-<span class="sourceLineNo">442</span><a name="line.442"></a>
-<span class="sourceLineNo">443</span>    // Perform a stochastic walk to see if we can get a good fit.<a name="line.443"></a>
-<span class="sourceLineNo">444</span>    long step;<a name="line.444"></a>
-<span class="sourceLineNo">445</span><a name="line.445"></a>
-<span class="sourceLineNo">446</span>    for (step = 0; step &lt; computedMaxSteps; step++) {<a name="line.446"></a>
-<span class="sourceLineNo">447</span>      Cluster.Action action = nextAction(cluster);<a name="line.447"></a>
-<span class="sourceLineNo">448</span><a name="line.448"></a>
-<span class="sourceLineNo">449</span>      if (action.type == Type.NULL) {<a name="line.449"></a>
-<span class="sourceLineNo">450</span>        continue;<a name="line.450"></a>
-<span class="sourceLineNo">451</span>      }<a name="line.451"></a>
-<span class="sourceLineNo">452</span><a name="line.452"></a>
-<span class="sourceLineNo">453</span>      cluster.doAction(action);<a name="line.453"></a>
-<span class="sourceLineNo">454</span>      updateCostsWithAction(cluster, action);<a name="line.454"></a>
-<span class="sourceLineNo">455</span><a name="line.455"></a>
-<span class="sourceLineNo">456</span>      newCost = computeCost(cluster, currentCost);<a name="line.456"></a>
+<span class="sourceLineNo">412</span>    initCosts(cluster);<a name="line.412"></a>
+<span class="sourceLineNo">413</span><a name="line.413"></a>
+<span class="sourceLineNo">414</span>    if (!needsBalance(cluster)) {<a name="line.414"></a>
+<span class="sourceLineNo">415</span>      return null;<a name="line.415"></a>
+<span class="sourceLineNo">416</span>    }<a name="line.416"></a>
+<span class="sourceLineNo">417</span><a name="line.417"></a>
+<span class="sourceLineNo">418</span>    double currentCost = computeCost(cluster, Double.MAX_VALUE);<a name="line.418"></a>
+<span class="sourceLineNo">419</span>    curOverallCost = currentCost;<a name="line.419"></a>
+<span class="sourceLineNo">420</span>    for (int i = 0; i &lt; this.curFunctionCosts.length; i++) {<a name="line.420"></a>
+<span class="sourceLineNo">421</span>      curFunctionCosts[i] = tempFunctionCosts[i];<a name="line.421"></a>
+<span class="sourceLineNo">422</span>    }<a name="line.422"></a>
+<span class="sourceLineNo">423</span>    double initCost = currentCost;<a name="line.423"></a>
+<span class="sourceLineNo">424</span>    double newCost = currentCost;<a name="line.424"></a>
+<span class="sourceLineNo">425</span><a name="line.425"></a>
+<span class="sourceLineNo">426</span>    long computedMaxSteps;<a name="line.426"></a>
+<span class="sourceLineNo">427</span>    if (runMaxSteps) {<a name="line.427"></a>
+<span class="sourceLineNo">428</span>      computedMaxSteps = Math.max(this.maxSteps,<a name="line.428"></a>
+<span class="sourceLineNo">429</span>          ((long)cluster.numRegions * (long)this.stepsPerRegion * (long)cluster.numServers));<a name="line.429"></a>
+<span class="sourceLineNo">430</span>    } else {<a name="line.430"></a>
+<span class="sourceLineNo">431</span>      long calculatedMaxSteps = (long)cluster.numRegions * (long)this.stepsPerRegion *<a name="line.431"></a>
+<span class="sourceLineNo">432</span>          (long)cluster.numServers;<a name="line.432"></a>
+<span class="sourceLineNo">433</span>      computedMaxSteps = Math.min(this.maxSteps, calculatedMaxSteps);<a name="line.433"></a>
+<span class="sourceLineNo">434</span>      if (calculatedMaxSteps &gt; maxSteps) {<a name="line.434"></a>
+<span class="sourceLineNo">435</span>        LOG.warn("calculatedMaxSteps:{} for loadbalancer's stochastic walk is larger than "<a name="line.435"></a>
+<span class="sourceLineNo">436</span>            + "maxSteps:{}. Hence load balancing may not work well. Setting parameter "<a name="line.436"></a>
+<span class="sourceLineNo">437</span>            + "\"hbase.master.balancer.stochastic.runMaxSteps\" to true can overcome this issue."<a name="line.437"></a>
+<span class="sourceLineNo">438</span>            + "(This config change does not require service restart)", calculatedMaxSteps,<a name="line.438"></a>
+<span class="sourceLineNo">439</span>            maxSteps);<a name="line.439"></a>
+<span class="sourceLineNo">440</span>      }<a name="line.440"></a>
+<span class="sourceLineNo">441</span>    }<a name="line.441"></a>
+<span class="sourceLineNo">442</span>    LOG.info("start StochasticLoadBalancer.balancer, initCost=" + currentCost + ", functionCost="<a name="line.442"></a>
+<span class="sourceLineNo">443</span>        + functionCost() + " computedMaxSteps: " + computedMaxSteps);<a name="line.443"></a>
+<span class="sourceLineNo">444</span><a name="line.444"></a>
+<span class="sourceLineNo">445</span>    // Perform a stochastic walk to see if we can get a good fit.<a name="line.445"></a>
+<span class="sourceLineNo">446</span>    long step;<a name="line.446"></a>
+<span class="sourceLineNo">447</span><a name="line.447"></a>
+<span class="sourceLineNo">448</span>    for (step = 0; step &lt; computedMaxSteps; step++) {<a name="line.448"></a>
+<span class="sourceLineNo">449</span>      Cluster.Action action = nextAction(cluster);<a name="line.449"></a>
+<span class="sourceLineNo">450</span><a name="line.450"></a>
+<span class="sourceLineNo">451</span>      if (action.type == Type.NULL) {<a name="line.451"></a>
+<span class="sourceLineNo">452</span>        continue;<a name="line.452"></a>
+<span class="sourceLineNo">453</span>      }<a name="line.453"></a>
+<span class="sourceLineNo">454</span><a name="line.454"></a>
+<span class="sourceLineNo">455</span>      cluster.doAction(action);<a name="line.455"></a>
+<span class="sourceLineNo">456</span>      updateCostsWithAction(cluster, action);<a name="line.456"></a>
 <span class="sourceLineNo">457</span><a name="line.457"></a>
-<span class="sourceLineNo">458</span>      // Should this be kept?<a name="line.458"></a>
-<span class="sourceLineNo">459</span>      if (newCost &lt; currentCost) {<a name="line.459"></a>
-<span class="sourceLineNo">460</span>        currentCost = newCost;<a name="line.460"></a>
-<span class="sourceLineNo">461</span><a name="line.461"></a>
-<span class="sourceLineNo">462</span>        // save for JMX<a name="line.462"></a>
-<span class="sourceLineNo">463</span>        curOverallCost = currentCost;<a name="line.463"></a>
-<span class="sourceLineNo">464</span>        for (int i = 0; i &lt; this.curFunctionCosts.length; i++) {<a name="line.464"></a>
-<span class="sourceLineNo">465</span>          curFunctionCosts[i] = tempFunctionCosts[i];<a name="line.465"></a>
-<span class="sourceLineNo">466</span>        }<a name="line.466"></a>
-<span class="sourceLineNo">467</span>      } else {<a name="line.467"></a>
-<span class="sourceLineNo">468</span>        // Put things back the way they were before.<a name="line.468"></a>
-<span class="sourceLineNo">469</span>        // TODO: undo by remembering old values<a name="line.469"></a>
-<span class="sourceLineNo">470</span>        Action undoAction = action.undoAction();<a name="line.470"></a>
-<span class="sourceLineNo">471</span>        cluster.doAction(undoAction);<a name="line.471"></a>
-<span class="sourceLineNo">472</span>        updateCostsWithAction(cluster, undoAction);<a name="line.472"></a>
-<span class="sourceLineNo">473</span>      }<a name="line.473"></a>
-<span class="sourceLineNo">474</span><a name="line.474"></a>
-<span class="sourceLineNo">475</span>      if (EnvironmentEdgeManager.currentTime() - startTime &gt;<a name="line.475"></a>
-<span class="sourceLineNo">476</span>          maxRunningTime) {<a name="line.476"></a>
-<span class="sourceLineNo">477</span>        break;<a name="line.477"></a>
-<span class="sourceLineNo">478</span>      }<a name="line.478"></a>
-<span class="sourceLineNo">479</span>    }<a name="line.479"></a>
-<span class="sourceLineNo">480</span>    long endTime = EnvironmentEdgeManager.currentTime();<a name="line.480"></a>
-<span class="sourceLineNo">481</span><a name="line.481"></a>
-<span class="sourceLineNo">482</span>    metricsBalancer.balanceCluster(endTime - startTime);<a name="line.482"></a>
+<span class="sourceLineNo">458</span>      newCost = computeCost(cluster, currentCost);<a name="line.458"></a>
+<span class="sourceLineNo">459</span><a name="line.459"></a>
+<span class="sourceLineNo">460</span>      // Should this be kept?<a name="line.460"></a>
+<span class="sourceLineNo">461</span>      if (newCost &lt; currentCost) {<a name="line.461"></a>
+<span class="sourceLineNo">462</span>        currentCost = newCost;<a name="line.462"></a>
+<span class="sourceLineNo">463</span><a name="line.463"></a>
+<span class="sourceLineNo">464</span>        // save for JMX<a name="line.464"></a>
+<span class="sourceLineNo">465</span>        curOverallCost = currentCost;<a name="line.465"></a>
+<span class="sourceLineNo">466</span>        for (int i = 0; i &lt; this.curFunctionCosts.length; i++) {<a name="line.466"></a>
+<span class="sourceLineNo">467</span>          curFunctionCosts[i] = tempFunctionCosts[i];<a name="line.467"></a>
+<span class="sourceLineNo">468</span>        }<a name="line.468"></a>
+<span class="sourceLineNo">469</span>      } else {<a name="line.469"></a>
+<span class="sourceLineNo">470</span>        // Put things back the way they were before.<a name="line.470"></a>
+<span class="sourceLineNo">471</span>        // TODO: undo by remembering old values<a name="line.471"></a>
+<span class="sourceLineNo">472</span>        Action undoAction = action.undoAction();<a name="line.472"></a>
+<span class="sourceLineNo">473</span>        cluster.doAction(undoAction);<a name="line.473"></a>
+<span class="sourceLineNo">474</span>        updateCostsWithAction(cluster, undoAction);<a name="line.474"></a>
+<span class="sourceLineNo">475</span>      }<a name="line.475"></a>
+<span class="sourceLineNo">476</span><a name="line.476"></a>
+<span class="sourceLineNo">477</span>      if (EnvironmentEdgeManager.currentTime() - startTime &gt;<a name="line.477"></a>
+<span class="sourceLineNo">478</span>          maxRunningTime) {<a name="line.478"></a>
+<span class="sourceLineNo">479</span>        break;<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>    long endTime = EnvironmentEdgeManager.currentTime();<a name="line.482"></a>
 <span class="sourceLineNo">483</span><a name="line.483"></a>
-<span class="sourceLineNo">484</span>    // update costs metrics<a name="line.484"></a>
-<span class="sourceLineNo">485</span>    updateStochasticCosts(tableName, curOverallCost, curFunctionCosts);<a name="line.485"></a>
-<span class="sourceLineNo">486</span>    if (initCost &gt; currentCost) {<a name="line.486"></a>
-<span class="sourceLineNo">487</span>      plans = createRegionPlans(cluster);<a name="line.487"></a>
-<span class="sourceLineNo">488</span>      LOG.info("Finished computing new load balance plan. Computation took {}" +<a name="line.488"></a>
-<span class="sourceLineNo">489</span>        " to try {} different iterations.  Found a solution that moves " +<a name="line.489"></a>
-<span class="sourceLineNo">490</span>        "{} regions; Going from a computed cost of {}" +<a name="line.490"></a>
-<span class="sourceLineNo">491</span>        " to a new cost of {}", java.time.Duration.ofMillis(endTime - startTime),<a name="line.491"></a>
-<span class="sourceLineNo">492</span>        step, plans.size(), initCost, currentCost);<a name="line.492"></a>
-<span class="sourceLineNo">493</span>      return plans;<a name="line.493"></a>
-<span class="sourceLineNo">494</span>    }<a name="line.494"></a>
-<span class="sourceLineNo">495</span>    LOG.info("Could not find a better load balance plan.  Tried {} different configurations in " +<a name="line.495"></a>
-<span class="sourceLineNo">496</span>      "{}, and did not find anything with a computed cost less than {}", step,<a name="line.496"></a>
-<span class="sourceLineNo">497</span>      java.time.Duration.ofMillis(endTime - startTime), initCost);<a name="line.497"></a>
-<span class="sourceLineNo">498</span>    return null;<a name="line.498"></a>
-<span class="sourceLineNo">499</span>  }<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>   * update costs to JMX<a name="line.502"></a>
-<span class="sourceLineNo">503</span>   */<a name="line.503"></a>
-<span class="sourceLineNo">504</span>  private void updateStochasticCosts(TableName tableName, Double overall, Double[] subCosts) {<a name="line.504"></a>
-<span class="sourceLineNo">505</span>    if (tableName == null) return;<a name="line.505"></a>
-<span class="sourceLineNo">506</span><a name="line.506"></a>
-<span class="sourceLineNo">507</span>    // check if the metricsBalancer is MetricsStochasticBalancer before casting<a name="line.507"></a>
-<span class="sourceLineNo">508</span>    if (metricsBalancer instanceof MetricsStochasticBalancer) {<a name="line.508"></a>
-<span class="sourceLineNo">509</span>      MetricsStochasticBalancer balancer = (MetricsStochasticBalancer) metricsBalancer;<a name="line.509"></a>
-<span class="sourceLineNo">510</span>      // overall cost<a name="line.510"></a>
-<span class="sourceLineNo">511</span>      balancer.updateStochasticCost(tableName.getNameAsString(),<a name="line.511"></a>
-<span class="sourceLineNo">512</span>        "Overall", "Overall cost", overall);<a name="line.512"></a>
-<span class="sourceLineNo">513</span><a name="line.513"></a>
-<span class="sourceLineNo">514</span>      // each cost function<a name="line.514"></a>
-<span class="sourceLineNo">515</span>      for (int i = 0; i &lt; costFunctions.size(); i++) {<a name="line.515"></a>
-<span class="sourceLineNo">516</span>        CostFunction costFunction = costFunctions.get(i);<a name="line.516"></a>
-<span class="sourceLineNo">517</span>        String costFunctionName = costFunction.getClass().getSimpleName();<a name="line.517"></a>
-<span class="sourceLineNo">518</span>        Double costPercent = (overall == 0) ? 0 : (subCosts[i] / overall);<a name="line.518"></a>
-<span class="sourceLineNo">519</span>        // TODO: cost function may need a specific description<a name="line.519"></a>
-<span class="sourceLineNo">520</span>        balancer.updateStochasticCost(tableName.getNameAsString(), costFunctionName,<a name="line.520"></a>
-<span class="sourceLineNo">521</span>          "The percent of " + costFunctionName, costPercent);<a name="line.521"></a>
-<span class="sourceLineNo">522</span>      }<a name="line.522"></a>
-<span class="sourceLineNo">523</span>    }<a name="line.523"></a>
-<span class="sourceLineNo">524</span>  }<a name="line.524"></a>
-<span class="sourceLineNo">525</span><a name="line.525"></a>
-<span class="sourceLineNo">526</span>  private String functionCost() {<a name="line.526"></a>
-<span class="sourceLineNo">527</span>    StringBuilder builder = new StringBuilder();<a name="line.527"></a>
-<span class="sourceLineNo">528</span>    for (CostFunction c:costFunctions) {<a name="line.528"></a>
-<span class="sourceLineNo">529</span>      builder.append(c.getClass().getSimpleName());<a name="line.529"></a>
-<span class="sourceLineNo">530</span>      builder.append(" : (");<a name="line.530"></a>
-<span class="sourceLineNo">531</span>      builder.append(c.getMultiplier());<a name="line.531"></a>
-<span class="sourceLineNo">532</span>      builder.append(", ");<a name="line.532"></a>
-<span class="sourceLineNo">533</span>      builder.append(c.cost());<a name="line.533"></a>
-<span class="sourceLineNo">534</span>      builder.append("); ");<a name="line.534"></a>
-<span class="sourceLineNo">535</span>    }<a name="line.535"></a>
-<span class="sourceLineNo">536</span>    return builder.toString();<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>  /**<a name="line.539"></a>
-<span class="sourceLineNo">540</span>   * Create all of the RegionPlan's needed to move from the initial cluster state to the desired<a name="line.540"></a>
-<span class="sourceLineNo">541</span>   * state.<a name="line.541"></a>
-<span class="sourceLineNo">542</span>   *<a name="line.542"></a>
-<span class="sourceLineNo">543</span>   * @param cluster The state of the cluster<a name="line.543"></a>
-<span class="sourceLineNo">544</span>   * @return List of RegionPlan's that represent the moves needed to get to desired final state.<a name="line.544"></a>
-<span class="sourceLineNo">545</span>   */<a name="line.545"></a>
-<span class="sourceLineNo">546</span>  private List&lt;RegionPlan&gt; createRegionPlans(Cluster cluster) {<a name="line.546"></a>
-<span class="sourceLineNo">547</span>    List&lt;RegionPlan&gt; plans = new LinkedList&lt;&gt;();<a name="line.547"></a>
-<span class="sourceLineNo">548</span>    for (int regionIndex = 0;<a name="line.548"></a>
-<span class="sourceLineNo">549</span>         regionIndex &lt; cluster.regionIndexToServerIndex.length; regionIndex++) {<a name="line.549"></a>
-<span class="sourceLineNo">550</span>      int initialServerIndex = cluster.initialRegionIndexToServerIndex[regionIndex];<a name="line.550"></a>
-<span class="sourceLineNo">551</span>      int newServerIndex = cluster.regionIndexToServerIndex[regionIndex];<a name="line.551"></a>
-<span class="sourceLineNo">552</span><a name="line.552"></a>
-<span class="sourceLineNo">553</span>      if (initialServerIndex != newServerIndex) {<a name="line.553"></a>
-<span class="sourceLineNo">554</span>        RegionInfo region = cluster.regions[regionIndex];<a name="line.554"></a>
-<span class="sourceLineNo">555</span>        ServerName initialServer = cluster.servers[initialServerIndex];<a name="line.555"></a>
-<span class="sourceLineNo">556</span>        ServerName newServer = cluster.servers[newServerIndex];<a name="line.556"></a>
-<span class="sourceLineNo">557</span><a name="line.557"></a>
-<span class="sourceLineNo">558</span>        if (LOG.isTraceEnabled()) {<a name="line.558"></a>
-<span class="sourceLineNo">559</span>          LOG.trace("Moving Region " + region.getEncodedName() + " from server "<a name="line.559"></a>
-<span class="sourceLineNo">560</span>              + initialServer.getHostname() + " to " + newServer.getHostname());<a name="line.560"></a>
-<span class="sourceLineNo">561</span>        }<a name="line.561"></a>
-<span class="sourceLineNo">562</span>        RegionPlan rp = new RegionPlan(region, initialServer, newServer);<a name="line.562"></a>
-<span class="sourceLineNo">563</span>        plans.add(rp);<a name="line.563"></a>
-<span class="sourceLineNo">564</span>      }<a name="line.564"></a>
-<span class="sourceLineNo">565</span>    }<a name="line.565"></a>
-<span class="sourceLineNo">566</span>    return plans;<a name="line.566"></a>
-<span class="sourceLineNo">567</span>  }<a name="line.567"></a>
-<span class="sourceLineNo">568</span><a name="line.568"></a>
-<span class="sourceLineNo">569</span>  /**<a name="line.569"></a>
-<span class="sourceLineNo">570</span>   * Store the current region loads.<a name="line.570"></a>
-<span class="sourceLineNo">571</span>   */<a name="line.571"></a>
-<span class="sourceLineNo">572</span>  private synchronized void updateRegionLoad() {<a name="line.572"></a>
-<span class="sourceLineNo">573</span>    // We create a new hashmap so that regions that are no longer there are removed.<a name="line.573"></a>
-<span class="sourceLineNo">574</span>    // However we temporarily need the old loads so we can use them to keep the rolling average.<a name="line.574"></a>
-<span class="sourceLineNo">575</span>    Map&lt;String, Deque&lt;BalancerRegionLoad&gt;&gt; oldLoads = loads;<a name="line.575"></a>
-<span class="sourceLineNo">576</span>    loads = new HashMap&lt;&gt;();<a name="line.576"></a>
-<span class="sourceLineNo">577</span><a name="line.577"></a>
-<span class="sourceLineNo">578</span>    clusterStatus.getLiveServerMetrics().forEach((ServerName sn, ServerMetrics sm) -&gt; {<a name="line.578"></a>
-<span class="sourceLineNo">579</span>      sm.getRegionMetrics().forEach((byte[] regionName, RegionMetrics rm) -&gt; {<a name="line.579"></a>
-<span class="sourceLineNo">580</span>        String regionNameAsString = RegionInfo.getRegionNameAsString(regionName);<a name="line.580"></a>
-<span class="sourceLineNo">581</span>        Deque&lt;BalancerRegionLoad&gt; rLoads = oldLoads.get(regionNameAsString);<a name="line.581"></a>
-<span class="sourceLineNo">582</span>        if (rLoads == null) {<a name="line.582"></a>
-<span class="sourceLineNo">583</span>          rLoads = new ArrayDeque&lt;&gt;(numRegionLoadsToRemember + 1);<a name="line.583"></a>
-<span class="sourceLineNo">584</span>        } else if (rLoads.size() &gt;= numRegionLoadsToRemember) {<a name="line.584"></a>
-<span class="sourceLineNo">585</span>          rLoads.remove();<a name="line.585"></a>
-<span class="sourceLineNo">586</span>        }<a name="line.586"></a>
-<span class="sourceLineNo">587</span>        rLoads.add(new BalancerRegionLoad(rm));<a name="line.587"></a>
-<span class="sourceLineNo">588</span>        loads.put(regionNameAsString, rLoads);<a name="line.588"></a>
-<span class="sourceLineNo">589</span>      });<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>    for(CostFromRegionLoadFunction cost : regionLoadFunctions) {<a name="line.592"></a>
-<span class="sourceLineNo">593</span>      cost.setLoads(loads);<a name="line.593"></a>
-<span class="sourceLineNo">594</span>    }<a name="line.594"></a>
-<span class="sourceLineNo">595</span>  }<a name="line.595"></a>
-<span class="sourceLineNo">596</span><a name="line.596"></a>
-<span class="sourceLineNo">597</span>  protected void initCosts(Cluster cluster) {<a name="line.597"></a>
-<span class="sourceLineNo">598</span>    for (CostFunction c:costFunctions) {<a name="line.598"></a>
-<span class="sourceLineNo">599</span>      c.init(cluster);<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>  protected void updateCostsWithAction(Cluster cluster, Action action) {<a name="line.603"></a>
-<span class="sourceLineNo">604</span>    for (CostFunction c : costFunctions) {<a name="line.604"></a>
-<span class="sourceLineNo">605</span>      c.postAction(action);<a name="line.605"></a>
-<span class="sourceLineNo">606</span>    }<a name="line.606"></a>
-<span class="sourceLineNo">607</span>  }<a name="line.607"></a>
-<span class="sourceLineNo">608</span><a name="line.608"></a>
-<span class="sourceLineNo">609</span>  /**<a name="line.609"></a>
-<span class="sourceLineNo">610</span>   * Get the names of the cost functions<a name="line.610"></a>
-<span class="sourceLineNo">611</span>   */<a name="line.611"></a>
-<span class="sourceLineNo">612</span>  public String[] getCostFunctionNames() {<a name="line.612"></a>
-<span class="sourceLineNo">613</span>    if (costFunctions == null) return null;<a name="line.613"></a>
-<span class="sourceLineNo">614</span>    String[] ret = new String[costFunctions.size()];<a name="line.614"></a>
-<span class="sourceLineNo">615</span>    for (int i = 0; i &lt; costFunctions.size(); i++) {<a name="line.615"></a>
-<span class="sourceLineNo">616</span>      CostFunction c = costFunctions.get(i);<a name="line.616"></a>
-<span class="sourceLineNo">617</span>      ret[i] = c.getClass().getSimpleName();<a name="line.617"></a>
-<span class="sourceLineNo">618</span>    }<a name="line.618"></a>
-<span class="sourceLineNo">619</span><a name="line.619"></a>
-<span class="sourceLineNo">620</span>    return ret;<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>   * This is the main cost function.  It will compute a cost associated with a proposed cluster<a name="line.624"></a>
-<span class="sourceLineNo">625</span>   * state.  All different costs will be combined with their multipliers to produce a double cost.<a name="line.625"></a>
-<span class="sourceLineNo">626</span>   *<a name="line.626"></a>
-<span class="sourceLineNo">627</span>   * @param cluster The state of the cluster<a name="line.627"></a>
-<span class="sourceLineNo">628</span>   * @param previousCost the previous cost. This is used as an early out.<a name="line.628"></a>
-<span class="sourceLineNo">629</span>   * @return a double of a cost associated with the proposed cluster state.  This cost is an<a name="line.629"></a>
-<span class="sourceLineNo">630</span>   *         aggregate of all individual cost functions.<a name="line.630"></a>
-<span class="sourceLineNo">631</span>   */<a name="line.631"></a>
-<span class="sourceLineNo">632</span>  protected double computeCost(Cluster cluster, double previousCost) {<a name="line.632"></a>
-<span class="sourceLineNo">633</span>    double total = 0;<a name="line.633"></a>
-<span class="sourceLineNo">634</span><a name="line.634"></a>
-<span class="sourceLineNo">635</span>    for (int i = 0; i &lt; costFunctions.size(); i++) {<a name="line.635"></a>
-<span class="sourceLineNo">636</span>      CostFunction c = costFunctions.get(i);<a name="line.636"></a>
-<span class="sourceLineNo">637</span>      this.tempFunctionCosts[i] = 0.0;<a name="line.637"></a>
-<span class="sourceLineNo">638</span><a name="line.638"></a>
-<span class="sourceLineNo">639</span>      if (c.getMultiplier() &lt;= 0) {<a name="line.639"></a>
-<span class="sourceLineNo">640</span>        continue;<a name="line.640"></a>
-<span class="sourceLineNo">641</span>      }<a name="line.641"></a>
-<span class="sourceLineNo">642</span><a name="line.642"></a>
-<span class="sourceLineNo">643</span>      Float multiplier = c.getMultiplier();<a name="line.643"></a>
-<span class="sourceLineNo">644</span>      Double cost = c.cost();<a name="line.644"></a>
-<span class="sourceLineNo">645</span><a name="line.645"></a>
-<span class="sourceLineNo">646</span>      this.tempFunctionCosts[i] = multiplier*cost;<a name="line.646"></a>
-<span class="sourceLineNo">647</span>      total += this.tempFunctionCosts[i];<a name="line.647"></a>
-<span class="sourceLineNo">648</span><a name="line.648"></a>
-<span class="sourceLineNo">649</span>      if (total &gt; previousCost) {<a name="line.649"></a>
-<span class="sourceLineNo">650</span>        break;<a name="line.650"></a>
-<span class="sourceLineNo">651</span>      }<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>    return total;<a name="line.654"></a>
-<span class="sourceLineNo">655</span>  }<a name="line.655"></a>
-<span class="sourceLineNo">656</span><a name="line.656"></a>
-<span class="sourceLineNo">657</span>  /** Generates a candidate action to be applied to the cluster for cost function search */<a name="line.657"></a>
-<span class="sourceLineNo">658</span>  abstract static class CandidateGenerator {<a name="line.658"></a>
-<span class="sourceLineNo">659</span>    abstract Cluster.Action generate(Cluster cluster);<a name="line.659"></a>
-<span class="sourceLineNo">660</span><a name="line.660"></a>
-<span class="sourceLineNo">661</span>    /**<a name="line.661"></a>
-<span class="sourceLineNo">662</span>     * From a list of regions pick a random one. Null can be returned which<a name="line.662"></a>
-<span class="sourceLineNo">663</span>     * {@link StochasticLoadBalancer#balanceCluster(Map)} recognize as signal to try a region move<a name="line.663"></a>
-<span class="sourceLineNo">664</span>     * rather than swap.<a name="line.664"></a>
-<span class="sourceLineNo">665</span>     *<a name="line.665"></a>
-<span class="sourceLineNo">666</span>     * @param cluster        The state of the cluster<a name="line.666"></a>
-<span class="sourceLineNo">667</span>     * @param server         index of the server<a name="line.667"></a>
-<span class="sourceLineNo">668</span>     * @param chanceOfNoSwap Chance that this will decide to try a move rather<a name="line.668"></a>
-<span class="sourceLineNo">669</span>     *                       than a swap.<a name="line.669"></a>
-<span class="sourceLineNo">670</span>     * @return a random {@link RegionInfo} or null if an asymmetrical move is<a name="line.670"></a>
-<span class="sourceLineNo">671</span>     *         suggested.<a name="line.671"></a>
-<span class="sourceLineNo">672</span>     */<a name="line.672"></a>
-<span class="sourceLineNo">673</span>    protected int pickRandomRegion(Cluster cluster, int server, double chanceOfNoSwap) {<a name="line.673"></a>
-<span class="sourceLineNo">674</span>      // Check to see if this is just a move.<a name="line.674"></a>
-<span class="sourceLineNo">675</span>      if (cluster.regionsPerServer[server].length == 0 || RANDOM.nextFloat() &lt; chanceOfNoSwap) {<a name="line.675"></a>
-<span class="sourceLineNo">676</span>        // signal a move only.<a name="line.676"></a>
-<span class="sourceLineNo">677</span>        return -1;<a name="line.677"></a>
-<span class="sourceLineNo">678</span>      }<a name="line.678"></a>
-<span class="sourceLineNo">679</span>      int rand = RANDOM.nextInt(cluster.regionsPerServer[server].length);<a name="line.679"></a>
-<span class="sourceLineNo">680</span>      return cluster.regionsPerServer[server][rand];<a name="line.680"></a>
-<span class="sourceLineNo">681</span><a name="line.681"></a>
-<span class="sourceLineNo">682</span>    }<a name="line.682"></a>
-<span class="sourceLineNo">683</span>    protected int pickRandomServer(Cluster cluster) {<a name="line.683"></a>
-<span class="sourceLineNo">684</span>      if (cluster.numServers &lt; 1) {<a name="line.684"></a>
-<span class="sourceLineNo">685</span>        return -1;<a name="line.685"></a>
-<span class="sourceLineNo">686</span>      }<a name="line.686"></a>
-<span class="sourceLineNo">687</span><a name="line.687"></a>
-<span class="sourceLineNo">688</span>      return RANDOM.nextInt(cluster.numServers);<a name="line.688"></a>
-<span class="sourceLineNo">689</span>    }<a name="line.689"></a>
-<span class="sourceLineNo">690</span><a name="line.690"></a>
-<span class="sourceLineNo">691</span>    protected int pickRandomRack(Cluster cluster) {<a name="line.691"></a>
-<span class="sourceLineNo">692</span>      if (cluster.numRacks &lt; 1) {<a name="line.692"></a>
-<span class="sourceLineNo">693</span>        return -1;<a name="line.693"></a>
-<span class="sourceLineNo">694</span>      }<a name="line.694"></a>
-<span class="sourceLineNo">695</span><a name="line.695"></a>
-<span class="sourceLineNo">696</span>      return RANDOM.nextInt(cluster.numRacks);<a name="line.696"></a>
-<span class="sourceLineNo">697</span>    }<a name="line.697"></a>
-<span class="sourceLineNo">698</span><a name="line.698"></a>
-<span class="sourceLineNo">699</span>    protected int pickOtherRandomServer(Cluster cluster, int serverIndex) {<a name="line.699"></a>
-<span class="sourceLineNo">700</span>      if (cluster.numServers &lt; 2) {<a name="line.700"></a>
-<span class="sourceLineNo">701</span>        return -1;<a name="line.701"></a>
-<span class="sourceLineNo">702</span>      }<a name="line.702"></a>
-<span class="sourceLineNo">703</span>      while (true) {<a name="line.703"></a>
-<span class="sourceLineNo">704</span>        int otherServerIndex = pickRandomServer(cluster);<a name="line.704"></a>
-<span class="sourceLineNo">705</span>        if (otherServerIndex != serverIndex) {<a name="line.705"></a>
-<span class="sourceLineNo">706</span>          return otherServerIndex;<a name="line.706"></a>
-<span class="sourceLineNo">707</span>        }<a name="line.707"></a>
-<span class="sourceLineNo">708</span>      }<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>    protected int pickOtherRandomRack(Cluster cluster, int rackIndex) {<a name="line.711"></a>
-<span class="sourceLineNo">712</span>      if (cluster.numRacks &lt; 2) {<a name="line.712"></a>
-<span class="sourceLineNo">713</span>        return -1;<a name="line.713"></a>
-<span class="sourceLineNo">714</span>      }<a name="line.714"></a>
-<span class="sourceLineNo">715</span>      while (true) {<a name="line.715"></a>
-<span class="sourceLineNo">716</span>        int otherRackIndex = pickRandomRack(cluster);<a name="line.716"></a>
-<span class="sourceLineNo">717</span>        if (otherRackIndex != rackIndex) {<a name="line.717"></a>
-<span class="sourceLineNo">718</span>          return otherRackIndex;<a name="line.718"></a>
-<span class="sourceLineNo">719</span>        }<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>    protected Cluster.Action pickRandomRegions(Cluster cluster,<a name="line.723"></a>
-<span class="sourceLineNo">724</span>                                                       int thisServer,<a name="line.724"></a>
-<span class="sourceLineNo">725</span>                                                       int otherServer) {<a name="line.725"></a>
-<span class="sourceLineNo">726</span>      if (thisServer &lt; 0 || otherServer &lt; 0) {<a name="line.726"></a>
-<span class="sourceLineNo">727</span>        return Cluster.NullAction;<a name="line.727"></a>
-<span class="sourceLineNo">728</span>      }<a name="line.728"></a>
-<span class="sourceLineNo">729</span><a name="line.729"></a>
-<span class="sourceLineNo">730</span>      // Decide who is most likely to need another region<a name="line.730"></a>
-<span class="sourceLineNo">731</span>      int thisRegionCount = cluster.getNumRegions(thisServer);<a name="line.731"></a>
-<span class="sourceLineNo">732</span>      int otherRegionCount = cluster.getNumRegions(otherServer);<a name="line.732"></a>
-<span class="sourceLineNo">733</span><a name="line.733"></a>
-<span class="sourceLineNo">734</span>      // Assign the chance based upon the above<a name="line.734"></a>
-<span class="sourceLineNo">735</span>      double thisChance = (thisRegionCount &gt; otherRegionCount) ? 0 : 0.5;<a name="line.735"></a>
-<span class="sourceLineNo">736</span>      double otherChance = (thisRegionCount &lt;= otherRegionCount) ? 0 : 0.5;<a name="line.736"></a>
-<span class="sourceLineNo">737</span><a name="line.737"></a>
-<span class="sourceLineNo">738</span>      int thisRegion = pickRandomRegion(cluster, thisServer, thisChance);<a name="line.738"></a>
-<span class="sourceLineNo">739</span>      int otherRegion = pickRandomRegion(cluster, otherServer, otherChance);<a name="line.739"></a>
-<span class="sourceLineNo">740</span><a name="line.740"></a>
-<span class="sourceLineNo">741</span>      return getAction(thisServer, thisRegion, otherServer, otherRegion);<a name="line.741"></a>
-<span class="sourceLineNo">742</span>    }<a name="line.742"></a>
-<span class="sourceLineNo">743</span><a name="line.743"></a>
-<span class="sourceLineNo">744</span>    protected Cluster.Action getAction(int fromServer, int fromRegion,<a name="line.744"></a>
-<span class="sourceLineNo">745</span>        int toServer, int toRegion) {<a name="line.745"></a>
-<span class="sourceLineNo">746</span>      if (fromServer &lt; 0 || toServer &lt; 0) {<a name="line.746"></a>
-<span class="sourceLineNo">747</span>        return Cluster.NullAction;<a name="line.747"></a>
-<span class="sourceLineNo">748</span>      }<a name="line.748"></a>
-<span class="sourceLineNo">749</span>      if (fromRegion &gt; 0 &amp;&amp; toRegion &gt; 0) {<a name="line.749"></a>
-<span class="sourceLineNo">750</span>        return new Cluster.SwapRegionsAction(fromServer, fromRegion,<a name="line.750"></a>
-<span class="sourceLineNo">751</span>          toServer, toRegion);<a name="line.751"></a>
-<span class="sourceLineNo">752</span>      } else if (fromRegion &gt; 0) {<a name="line.752"></a>
-<span class="sourceLineNo">753</span>        return new Cluster.MoveRegionAction(fromRegion, fromServer, toServer);<a name="line.753"></a>
-<span class="sourceLineNo">754</span>      } else if (toRegion &gt; 0) {<a name="line.754"></a>
-<span class="sourceLineNo">755</span>        return new Cluster.MoveRegionAction(toRegion, toServer, fromServer);<a name="line.755"></a>
-<span class="sourceLineNo">756</span>      } else {<a name="line.756"></a>
-<span class="sourceLineNo">757</span>        return Cluster.NullAction;<a name="line.757"></a>
-<span class="sourceLineNo">758</span>      }<a name="line.758"></a>
-<span class="sourceLineNo">759</span>    }<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>     * Returns a random iteration order of indexes of an array with size length<a name="line.762"></a>
-<span class="sourceLineNo">763</span>     */<a name="line.763"></a>
-<span class="sourceLineNo">764</span>    protected List&lt;Integer&gt; getRandomIterationOrder(int length) {<a name="line.764"></a>
-<span class="sourceLineNo">765</span>      ArrayList&lt;Integer&gt; order = new ArrayList&lt;&gt;(length);<a name="line.765"></a>
-<span class="sourceLineNo">766</span>      for (int i = 0; i &lt; length; i++) {<a name="line.766"></a>
-<span class="sourceLineNo">767</span>        order.add(i);<a name="line.767"></a>
-<span class="sourceLineNo">768</span>      }<a name="line.768"></a>
-<span class="sourceLineNo">769</span>      Collections.shuffle(order);<a name="line.769"></a>
-<span class="sourceLineNo">770</span>      return order;<a name="line.770"></a>
-<span class="sourceLineNo">771</span>    }<a name="line.771"></a>
-<span class="sourceLineNo">772</span>  }<a name="line.772"></a>
-<span class="sourceLineNo">773</span><a name="line.773"></a>
-<span class="sourceLineNo">774</span>  static class RandomCandidateGenerator extends CandidateGenerator {<a name="line.774"></a>
+<span class="sourceLineNo">484</span>    metricsBalancer.balanceCluster(endTime - startTime);<a name="line.484"></a>
+<span class="sourceLineNo">485</span><a name="line.485"></a>
+<span class="sourceLineNo">486</span>    // update costs metrics<a name="line.486"></a>
+<span class="sourceLineNo">487</span>    updateStochasticCosts(tableName, curOverallCost, curFunctionCosts);<a name="line.487"></a>
+<span class="sourceLineNo">488</span>    if (initCost &gt; currentCost) {<a name="line.488"></a>
+<span class="sourceLineNo">489</span>      plans = createRegionPlans(cluster);<a name="line.489"></a>
+<span class="sourceLineNo">490</span>      LOG.info("Finished computing new load balance plan. Computation took {}" +<a name="line.490"></a>
+<span class="sourceLineNo">491</span>        " to try {} different iterations.  Found a solution that moves " +<a name="line.491"></a>
+<span class="sourceLineNo">492</span>        "{} regions; Going from a computed cost of {}" +<a name="line.492"></a>
+<span class="sourceLineNo">493</span>        " to a new cost of {}", java.time.Duration.ofMillis(endTime - startTime),<a name="line.493"></a>
+<span class="sourceLineNo">494</span>        step, plans.size(), initCost, currentCost);<a name="line.494"></a>
+<span class="sourceLineNo">495</span>      return plans;<a name="line.495"></a>
+<span class="sourceLineNo">496</span>    }<a name="line.496"></a>
+<span class="sourceLineNo">497</span>    LOG.info("Could not find a better load balance plan.  Tried {} different configurations in " +<a name="line.497"></a>
+<span class="sourceLineNo">498</span>      "{}, and did not find anything with a computed cost less than {}", step,<a name="line.498"></a>
+<span class="sourceLineNo">499</span>      java.time.Duration.ofMillis(endTime - startTime), initCost);<a name="line.499"></a>
+<span class="sourceLineNo">500</span>    return null;<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>  /**<a name="line.503"></a>
+<span class="sourceLineNo">504</span>   * update costs to JMX<a name="line.504"></a>
+<span class="sourceLineNo">505</span>   */<a name="line.505"></a>
+<span class="sourceLineNo">506</span>  private void updateStochasticCosts(TableName tableName, Double overall, Double[] subCosts) {<a name="line.506"></a>
+<span class="sourceLineNo">507</span>    if (tableName == null) return;<a name="line.507"></a>
+<span class="sourceLineNo">508</span><a name="line.508"></a>
+<span class="sourceLineNo">509</span>    // check if the metricsBalancer is MetricsStochasticBalancer before casting<a name="line.509"></a>
+<span class="sourceLineNo">510</span>    if (metricsBalancer instanceof MetricsStochasticBalancer) {<a name="line.510"></a>
+<span class="sourceLineNo">511</span>      MetricsStochasticBalancer balancer = (MetricsStochasticBalancer) metricsBalancer;<a name="line.511"></a>
+<span class="sourceLineNo">512</span>      // overall cost<a name="line.512"></a>
+<span class="sourceLineNo">513</span>      balancer.updateStochasticCost(tableName.getNameAsString(),<a name="line.513"></a>
+<span class="sourceLineNo">514</span>        "Overall", "Overall cost", overall);<a name="line.514"></a>
+<span class="sourceLineNo">515</span><a name="line.515"></a>
+<span class="sourceLineNo">516</span>      // each cost function<a name="line.516"></a>
+<span class="sourceLineNo">517</span>      for (int i = 0; i &lt; costFunctions.size(); i++) {<a name="line.517"></a>
+<span class="sourceLineNo">518</span>        CostFunction costFunction = costFunctions.get(i);<a name="line.518"></a>
+<span class="sourceLineNo">519</span>        String costFunctionName = costFunction.getClass().getSimpleName();<a name="line.519"></a>
+<span class="sourceLineNo">520</span>        Double costPercent = (overall == 0) ? 0 : (subCosts[i] / overall);<a name="line.520"></a>
+<span class="sourceLineNo">521</span>        // TODO: cost function may need a specific description<a name="line.521"></a>
+<span class="sourceLineNo">522</span>        balancer.updateStochasticCost(tableName.getNameAsString(), costFunctionName,<a name="line.522"></a>
+<span class="sourceLineNo">523</span>          "The percent of " + costFunctionName, costPercent);<a name="line.523"></a>
+<span class="sourceLineNo">524</span>      }<a name="line.524"></a>
+<span class="sourceLineNo">525</span>    }<a name="line.525"></a>
+<span class="sourceLineNo">526</span>  }<a name="line.526"></a>
+<span class="sourceLineNo">527</span><a name="line.527"></a>
+<span class="sourceLineNo">528</span>  private String functionCost() {<a name="line.528"></a>
+<span class="sourceLineNo">529</span>    StringBuilder builder = new StringBuilder();<a name="line.529"></a>
+<span class="sourceLineNo">530</span>    for (CostFunction c:costFunctions) {<a name="line.530"></a>
+<span class="sourceLineNo">531</span>      builder.append(c.getClass().getSimpleName());<a name="line.531"></a>
+<span class="sourceLineNo">532</span>      builder.append(" : (");<a name="line.532"></a>
+<span class="sourceLineNo">533</span>      builder.append(c.getMultiplier());<a name="line.533"></a>
+<span class="sourceLineNo">534</span>      builder.append(", ");<a name="line.534"></a>
+<span class="sourceLineNo">535</span>      builder.append(c.cost());<a name="line.535"></a>
+<span class="sourceLineNo">536</span>      builder.append("); ");<a name="line.536"></a>
+<span class="sourceLineNo">537</span>    }<a name="line.537"></a>
+<span class="sourceLineNo">538</span>    return builder.toString();<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>  /**<a name="line.541"></a>
+<span class="sourceLineNo">542</span>   * Create all of the RegionPlan's needed to move from the initial cluster state to the desired<a name="line.542"></a>
+<span class="sourceLineNo">543</span>   * state.<a name="line.543"></a>
+<span class="sourceLineNo">544</span>   *<a name="line.544"></a>
+<span class="sourceLineNo">545</span>   * @param cluster The state of the cluster<a name="line.545"></a>
+<span class="sourceLineNo">546</span>   * @return List of RegionPlan's that represent the moves needed to get to desired final state.<a name="line.546"></a>
+<span class="sourceLineNo">547</span>   */<a name="line.547"></a>
+<span class="sourceLineNo">548</span>  private List&lt;RegionPlan&gt; createRegionPlans(Cluster cluster) {<a name="line.548"></a>
+<span class="sourceLineNo">549</span>    List&lt;RegionPlan&gt; plans = new LinkedList&lt;&gt;();<a name="line.549"></a>
+<span class="sourceLineNo">550</span>    for (int regionIndex = 0;<a name="line.550"></a>
+<span class="sourceLineNo">551</span>         regionIndex &lt; cluster.regionIndexToServerIndex.length; regionIndex++) {<a name="line.551"></a>
+<span class="sourceLineNo">552</span>      int initialServerIndex = cluster.initialRegionIndexToServerIndex[regionIndex];<a name="line.552"></a>
+<span class="sourceLineNo">553</span>      int newServerIndex = cluster.regionIndexToServerIndex[regionIndex];<a name="line.553"></a>
+<span class="sourceLineNo">554</span><a name="line.554"></a>
+<span class="sourceLineNo">555</span>      if (initialServerIndex != newServerIndex) {<a name="line.555"></a>
+<span class="sourceLineNo">556</span>        RegionInfo region = cluster.regions[regionIndex];<a name="line.556"></a>
+<span class="sourceLineNo">557</span>        ServerName initialServer = cluster.servers[initialServerIndex];<a name="line.557"></a>
+<span class="sourceLineNo">558</span>        ServerName newServer = cluster.servers[newServerIndex];<a name="line.558"></a>
+<span class="sourceLineNo">559</span><a name="line.559"></a>
+<span class="sourceLineNo">560</span>        if (LOG.isTraceEnabled()) {<a name="line.560"></a>
+<span class="sourceLineNo">561</span>          LOG.trace("Moving Region " + region.getEncodedName() + " from server "<a name="line.561"></a>
+<span class="sourceLineNo">562</span>              + initialServer.getHostname() + " to " + newServer.getHostname());<a name="line.562"></a>
+<span class="sourceLineNo">563</span>        }<a name="line.563"></a>
+<span class="sourceLineNo">564</span>        RegionPlan rp = new RegionPlan(region, initialServer, newServer);<a name="line.564"></a>
+<span class="sourceLineNo">565</span>        plans.add(rp);<a name="line.565"></a>
+<span class="sourceLineNo">566</span>      }<a name="line.566"></a>
+<span class="sourceLineNo">567</span>    }<a name="line.567"></a>
+<span class="sourceLineNo">568</span>    return plans;<a name="line.568"></a>
+<span class="sourceLineNo">569</span>  }<a name="line.569"></a>
+<span class="sourceLineNo">570</span><a name="line.570"></a>
+<span class="sourceLineNo">571</span>  /**<a name="line.571"></a>
+<span class="sourceLineNo">572</span>   * Store the current region loads.<a name="line.572"></a>
+<span class="sourceLineNo">573</span>   */<a name="line.573"></a>
+<span class="sourceLineNo">574</span>  private synchronized void updateRegionLoad() {<a name="line.574"></a>
+<span class="sourceLineNo">575</span>    // We create a new hashmap so that regions that are no longer there are removed.<a name="line.575"></a>
+<span class="sourceLineNo">576</span>    // However we temporarily need the old loads so we can use them to keep the rolling average.<a name="line.576"></a>
+<span class="sourceLineNo">577</span>    Map&lt;String, Deque&lt;BalancerRegionLoad&gt;&gt; oldLoads = loads;<a name="line.577"></a>
+<span class="sourceLineNo">578</span>    loads = new HashMap&lt;&gt;();<a name="line.578"></a>
+<span class="sourceLineNo">579</span><a name="line.579"></a>
+<span class="sourceLineNo">580</span>    clusterStatus.getLiveServerMetrics().forEach((ServerName sn, ServerMetrics sm) -&gt; {<a name="line.580"></a>
+<span class="sourceLineNo">581</span>      sm.getRegionMetrics().forEach((byte[] regionName, RegionMetrics rm) -&gt; {<a name="line.581"></a>
+<span class="sourceLineNo">582</span>        String regionNameAsString = RegionInfo.getRegionNameAsString(regionName);<a name="line.582"></a>
+<span class="sourceLineNo">583</span>        Deque&lt;BalancerRegionLoad&gt; rLoads = oldLoads.get(regionNameAsString);<a name="line.583"></a>
+<span class="sourceLineNo">584</span>        if (rLoads == null) {<a name="line.584"></a>
+<span class="sourceLineNo">585</span>          rLoads = new ArrayDeque&lt;&gt;(numRegionLoadsToRemember + 1);<a name="line.585"></a>
+<span class="sourceLineNo">586</span>        } else if (rLoads.size() &gt;= numRegionLoadsToRemember) {<a name="line.586"></a>
+<span class="sourceLineNo">587</span>          rLoads.remove();<a name="line.587"></a>
+<span class="sourceLineNo">588</span>        }<a name="line.588"></a>
+<span class="sourceLineNo">589</span>        rLoads.add(new BalancerRegionLoad(rm));<a name="line.589"></a>
+<span class="sourceLineNo">590</span>        loads.put(regionNameAsString, rLoads);<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>    for(CostFromRegionLoadFunction cost : regionLoadFunctions) {<a name="line.594"></a>
+<span class="sourceLineNo">595</span>      cost.setLoads(loads);<a name="line.595"></a>
+<span class="sourceLineNo">596</span>    }<a name="line.596"></a>
+<span class="sourceLineNo">597</span>  }<a name="line.597"></a>
+<span class="sourceLineNo">598</span><a name="line.598"></a>
+<span class="sourceLineNo">599</span>  protected void initCosts(Cluster cluster) {<a name="line.599"></a>
+<span class="sourceLineNo">600</span>    for (CostFunction c:costFunctions) {<a name="line.600"></a>
+<span class="sourceLineNo">601</span>      c.init(cluster);<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><a name="line.604"></a>
+<span class="sourceLineNo">605</span>  protected void updateCostsWithAction(Cluster cluster, Action action) {<a name="line.605"></a>
+<span class="sourceLineNo">606</span>    for (CostFunction c : costFunctions) {<a name="line.606"></a>
+<span class="sourceLineNo">607</span>      c.postAction(action);<a name="line.607"></a>
+<span class="sourceLineNo">608</span>    }<a name="line.608"></a>
+<span class="sourceLineNo">609</span>  }<a name="line.609"></a>
+<span class="sourceLineNo">610</span><a name="line.610"></a>
+<span class="sourceLineNo">611</span>  /**<a name="line.611"></a>
+<span class="sourceLineNo">612</span>   * Get the names of the cost functions<a name="line.612"></a>
+<span class="sourceLineNo">613</span>   */<a name="line.613"></a>
+<span class="sourceLineNo">614</span>  public String[] getCostFunctionNames() {<a name="line.614"></a>
+<span class="sourceLineNo">615</span>    if (costFunctions == null) return null;<a name="line.615"></a>
+<span class="sourceLineNo">616</span>    String[] ret = new String[costFunctions.size()];<a name="line.616"></a>
+<span class="sourceLineNo">617</span>    for (int i = 0; i &lt; costFunctions.size(); i++) {<a name="line.617"></a>
+<span class="sourceLineNo">618</span>      CostFunction c = costFunctions.get(i);<a name="line.618"></a>
+<span class="sourceLineNo">619</span>      ret[i] = c.getClass().getSimpleName();<a name="line.619"></a>
+<span class="sourceLineNo">620</span>    }<a name="line.620"></a>
+<span class="sourceLineNo">621</span><a name="line.621"></a>
+<span class="sourceLineNo">622</span>    return ret;<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>  /**<a name="line.625"></a>
+<span class="sourceLineNo">626</span>   * This is the main cost function.  It will compute a cost associated with a proposed cluster<a name="line.626"></a>
+<span class="sourceLineNo">627</span>   * state.  All different costs will be combined with their multipliers to produce a double cost.<a name="line.627"></a>
+<span class="sourceLineNo">628</span>   *<a name="line.628"></a>
+<span class="sourceLineNo">629</span>   * @param cluster The state of the cluster<a name="line.629"></a>
+<span class="sourceLineNo">630</span>   * @param previousCost the previous cost. This is used as an early out.<a name="line.630"></a>
+<span class="sourceLineNo">631</span>   * @return a double of a cost associated with the proposed cluster state.  This cost is an<a name="line.631"></a>
+<span class="sourceLineNo">632</span>   *         aggregate of all individual cost functions.<a name="line.632"></a>
+<span class="sourceLineNo">633</span>   */<a name="line.633"></a>
+<span class="sourceLineNo">634</span>  protected double computeCost(Cluster cluster, double previousCost) {<a name="line.634"></a>
+<span class="sourceLineNo">635</span>    double total = 0;<a name="line.635"></a>
+<span class="sourceLineNo">636</span><a name="line.636"></a>
+<span class="sourceLineNo">637</span>    for (int i = 0; i &lt; costFunctions.size(); i++) {<a name="line.637"></a>
+<span class="sourceLineNo">638</span>      CostFunction c = costFunctions.get(i);<a name="line.638"></a>
+<span class="sourceLineNo">639</span>      this.tempFunctionCosts[i] = 0.0;<a name="line.639"></a>
+<span class="sourceLineNo">640</span><a name="line.640"></a>
+<span class="sourceLineNo">641</span>      if (c.getMultiplier() &lt;= 0) {<a name="line.641"></a>
+<span class="sourceLineNo">642</span>        continue;<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>      Float multiplier = c.getMultiplier();<a name="line.645"></a>
+<span class="sourceLineNo">646</span>      Double cost = c.cost();<a name="line.646"></a>
+<span class="sourceLineNo">647</span><a name="line.647"></a>
+<span class="sourceLineNo">648</span>      this.tempFunctionCosts[i] = multiplier*cost;<a name="line.648"></a>
+<span class="sourceLineNo">649</span>      total += this.tempFunctionCosts[i];<a name="line.649"></a>
+<span class="sourceLineNo">650</span><a name="line.650"></a>
+<span class="sourceLineNo">651</span>      if (total &gt; previousCost) {<a name="line.651"></a>
+<span class="sourceLineNo">652</span>        break;<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><a name="line.655"></a>
+<span class="sourceLineNo">656</span>    return total;<a name="line.656"></a>
+<span class="sourceLineNo">657</span>  }<a name="line.657"></a>
+<span class="sourceLineNo">658</span><a name="line.658"></a>
+<span class="sourceLineNo">659</span>  /** Generates a candidate action to be applied to the cluster for cost function search */<a name="line.659"></a>
+<span class="sourceLineNo">660</span>  abstract static class CandidateGenerator {<a name="line.660"></a>
+<span class="sourceLineNo">661</span>    abstract Cluster.Action generate(Cluster cluster);<a name="line.661"></a>
+<span class="sourceLineNo">662</span><a name="line.662"></a>
+<span class="sourceLineNo">663</span>    /**<a name="line.663"></a>
+<span class="sourceLineNo">664</span>     * From a list of regions pick a random one. Null can be returned which<a name="line.664"></a>
+<span class="sourceLineNo">665</span>     * {@link StochasticLoadBalancer#balanceCluster(Map)} recognize as signal to try a region move<a name="line.665"></a>
+<span class="sourceLineNo">666</span>     * rather than swap.<a name="line.666"></a>
+<span class="sourceLineNo">667</span>     *<a name="line.667"></a>
+<span class="sourceLineNo">668</span>     * @param cluster        The state of the cluster<a name="line.668"></a>
+<span class="sourceLineNo">669</span>     * @param server         index of the server<a name="line.669"></a>
+<span class="sourceLineNo">670</span>     * @param chanceOfNoSwap Chance that this will decide to try a move rather<a name="line.670"></a>
+<span class="sourceLineNo">671</span>     *                       than a swap.<a name="line.671"></a>
+<span class="sourceLineNo">672</span>     * @return a random {@link RegionInfo} or null if an asymmetrical move is<a name="line.672"></a>
+<span class="sourceLineNo">673</span>     *         suggested.<a name="line.673"></a>
+<span class="sourceLineNo">674</span>     */<a name="line.674"></a>
+<span class="sourceLineNo">675</span>    protected int pickRandomRegion(Cluster cluster, int server, double chanceOfNoSwap) {<a name="line.675"></a>
+<span class="sourceLineNo">676</span>      // Check to see if this is just a move.<a name="line.676"></a>
+<span class="sourceLineNo">677</span>      if (cluster.regionsPerServer[server].length == 0 || RANDOM.nextFloat() &lt; chanceOfNoSwap) {<a name="line.677"></a>
+<span class="sourceLineNo">678</span>        // signal a move only.<a name="line.678"></a>
+<span class="sourceLineNo">679</span>        return -1;<a name="line.679"></a>
+<span class="sourceLineNo">680</span>      }<a name="line.680"></a>
+<span class="sourceLineNo">681</span>      int rand = RANDOM.nextInt(cluster.regionsPerServer[server].length);<a name="line.681"></a>
+<span class="sourceLineNo">682</span>      return cluster.regionsPerServer[server][rand];<a name="line.682"></a>
+<span class="sourceLineNo">683</span><a name="line.683"></a>
+<span class="sourceLineNo">684</span>    }<a name="line.684"></a>
+<span class="sourceLineNo">685</span>    protected int pickRandomServer(Cluster cluster) {<a name="line.685"></a>
+<span class="sourceLineNo">686</span>      if (cluster.numServers &lt; 1) {<a name="line.686"></a>
+<span class="sourceLineNo">687</span>        return -1;<a name="line.687"></a>
+<span class="sourceLineNo">688</span>      }<a name="line.688"></a>
+<span class="sourceLineNo">689</span><a name="line.689"></a>
+<span class="sourceLineNo">690</span>      return RANDOM.nextInt(cluster.numServers);<a name="line.690"></a>
+<span class="sourceLineNo">691</span>    }<a name="line.691"></a>
+<span class="sourceLineNo">692</span><a name="line.692"></a>
+<span class="sourceLineNo">693</span>    protected int pickRandomRack(Cluster cluster) {<a name="line.693"></a>
+<span class="sourceLineNo">694</span>      if (cluster.numRacks &lt; 1) {<a name="line.694"></a>
+<span class="sourceLineNo">695</span>        return -1;<a name="line.695"></a>
+<span class="sourceLineNo">696</span>      }<a name="line.696"></a>
+<span class="sourceLineNo">697</span><a name="line.697"></a>
+<span class="sourceLineNo">698</span>      return RANDOM.nextInt(cluster.numRacks);<a name="line.698"></a>
+<span class="sourceLineNo">699</span>    }<a name="line.699"></a>
+<span class="sourceLineNo">700</span><a name="line.700"></a>
+<span class="sourceLineNo">701</span>    protected int pickOtherRandomServer(Cluster cluster, int serverIndex) {<a name="line.701"></a>
+<span class="sourceLineNo">702</span>      if (cluster.numServers &lt; 2) {<a name="line.702"></a>
+<span class="sourceLineNo">703</span>        return -1;<a name="line.703"></a>
+<span class="sourceLineNo">704</span>      }<a name="line.704"></a>
+<span class="sourceLineNo">705</span>      while (true) {<a name="line.705"></a>
+<span class="sourceLineNo">706</span>        int otherServerIndex = pickRandomServer(cluster);<a name="line.706"></a>
+<span class="sourceLineNo">707</span>        if (otherServerIndex != serverIndex) {<a name="line.707"></a>
+<span class="sourceLineNo">708</span>          return otherServerIndex;<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><a name="line.712"></a>
+<span class="sourceLineNo">713</span>    protected int pickOtherRandomRack(Cluster cluster, int rackIndex) {<a name="line.713"></a>
+<span class="sourceLineNo">714</span>      if (cluster.numRacks &lt; 2) {<a name="line.714"></a>
+<span class="sourceLineNo">715</span>        return -1;<a name="line.715"></a>
+<span class="sourceLineNo">716</span>      }<a name="line.716"></a>
+<span class="sourceLineNo">717</span>      while (true) {<a name="line.717"></a>
+<span class="sourceLineNo">718</span>        int otherRackIndex = pickRandomRack(cluster);<a name="line.718"></a>
+<span class="sourceLineNo">719</span>        if (otherRackIndex != rackIndex) {<a name="line.719"></a>
+<span class="sourceLineNo">720</span>          return otherRackIndex;<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><a name="line.724"></a>
+<span class="sourceLineNo">725</span>    protected Cluster.Action pickRandomRegions(Cluster cluster,<a name="line.725"></a>
+<span class="sourceLineNo">726</span>                                                       int thisServer,<a name="line.726"></a>
+<span class="sourceLineNo">727</span>                                                       int otherServer) {<a name="line.727"></a>
+<span class="sourceLineNo">728</span>      if (thisServer &lt; 0 || otherServer &lt; 0) {<a name="line.728"></a>
+<span class="sourceLineNo">729</span>        return Cluster.NullAction;<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>      // Decide who is most likely to need another region<a name="line.732"></a>
+<span class="sourceLineNo">733</span>      int thisRegionCount = cluster.getNumRegions(thisServer);<a name="line.733"></a>
+<span class="sourceLineNo">734</span>      int otherRegionCount = cluster.getNumRegions(otherServer);<a name="line.734"></a>
+<span class="sourceLineNo">735</span><a name="line.735"></a>
+<span class="sourceLineNo">736</span>      // Assign the chance based upon the above<a name="line.736"></a>
+<span class="sourceLineNo">737</span>      double thisChance = (thisRegionCount &gt; otherRegionCount) ? 0 : 0.5;<a name="line.737"></a>
+<span class="sourceLineNo">738</span>      double otherChance = (thisRegionCount &lt;= otherRegionCount) ? 0 : 0.5;<a name="line.738"></a>
+<span class="sourceLineNo">739</span><a name="line.739"></a>
+<span class="sourceLineNo">740</span>      int thisRegion = pickRandomRegion(cluster, thisServer, thisChance);<a name="line.740"></a>
+<span class="sourceLineNo">741</span>      int otherRegion = pickRandomRegion(cluster, otherServer, otherChance);<a name="line.741"></a>
+<span class="sourceLineNo">742</span><a name="line.742"></a>
+<span class="sourceLineNo">743</span>      return getAction(thisServer, thisRegion, otherServer, otherRegion);<a name="line.743"></a>
+<span class="sourceLineNo">744</span>    }<a name="line.744"></a>
+<span class="sourceLineNo">745</span><a name="line.745"></a>
+<span class="sourceLineNo">746</span>    protected Cluster.Action getAction(int fromServer, int fromRegion,<a name="line.746"></a>
+<span class="sourceLineNo">747</span>        int toServer, int toRegion) {<a name="line.747"></a>
+<span class="sourceLineNo">748</span>      if (fromServer &lt; 0 || toServer &lt; 0) {<a name="line.748"></a>
+<span class="sourceLineNo">749</span>        return Cluster.NullAction;<a name="line.749"></a>
+<span class="sourceLineNo">750</span>      }<a name="line.750"></a>
+<span class="sourceLineNo">751</span>      if (fromRegion &gt; 0 &amp;&amp; toRegion &gt; 0) {<a name="line.751"></a>
+<span class="sourceLineNo">752</span>        return new Cluster.SwapRegionsAction(fromServer, fromRegion,<a name="line.752"></a>
+<span class="sourceLineNo">753</span>          toServer, toRegion);<a name="line.753"></a>
+<span class="sourceLineNo">754</span>      } else if (fromRegion &gt; 0) {<a name="line.754"></a>
+<span class="sourceLineNo">755</span>        return new Cluster.MoveRegionAction(fromRegion, fromServer, toServer);<a name="line.755"></a>
+<span class="sourceLineNo">756</span>      } else if (toRegion &gt; 0) {<a name="line.756"></a>
+<span class="sourceLineNo">757</span>        return new Cluster.MoveRegionAction(toRegion, toServer, fromServer);<a name="line.757"></a>
+<span class="sourceLineNo">758</span>      } else {<a name="line.758"></a>
+<span class="sourceLineNo">759</span>        return Cluster.NullAction;<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><a name="line.762"></a>
+<span class="sourceLineNo">763</span>    /**<a name="line.763"></a>
+<span class="sourceLineNo">764</span>     * Returns a random iteration order of indexes of an array with size length<a name="line.764"></a>
+<span class="sourceLineNo">765</span>     */<a name="line.765"></a>
+<span class="sourceLineNo">766</span>    protected List&lt;Integer&gt; getRandomIterationOrder(int length) {<a name="line.766"></a>
+<span class="sourceLineNo">767</span>      ArrayList&lt;Integer&gt; order = new ArrayList&lt;&gt;(length);<a name="line.767"></a>
+<span class="sourceLineNo">768</span>      for (int i = 0; i &lt; length; i++) {<a name="line.768"></a>
+<span class="sourceLineNo">769</span>        order.add(i);<a name="line.769"></a>
+<span class="sourceLineNo">770</span>      }<a name="line.770"></a>
+<span class="sourceLineNo">771</span>      Collections.shuffle(order);<a name="line.771"></a>
+<span class="sourceLineNo">772</span>      return order;<a name="line.772"></a>
+<span class="sourceLineNo">773</span>    }<a name="line.773"></a>
+<span class="sourceLineNo">774</span>  }<a name="line.774"></a>
 <span class="sourceLineNo">775</span><a name="line.775"></a>
-<span class="sourceLineNo">776</span>    @Override<a name="line.776"></a>
-<span class="sourceLineNo">777</span>    Cluster.Action generate(Cluster cluster) {<a name="line.777"></a>
-<span class="sourceLineNo">778</span><a name="line.778"></a>
-<span class="sourceLineNo">779</span>      int thisServer = pickRandomServer(cluster);<a name="line.779"></a>
+<span class="sourceLineNo">776</span>  static class RandomCandidateGenerator extends CandidateGenerator {<a name="line.776"></a>
+<span class="sourceLineNo">777</span><a name="line.777"></a>
+<span class="sourceLineNo">778</span>    @Override<a name="line.778"></a>
+<span class="sourceLineNo">779</span>    Cluster.Action generate(Cluster cluster) {<a name="line.779"></a>
 <span class="sourceLineNo">780</span><a name="line.780"></a>
-<span class="sourceLineNo">781</span>      // Pick the other server<a name="line.781"></a>
-<span class="sourceLineNo">782</span>      int otherServer = pickOtherRandomServer(cluster, thisServer);<a name="line.782"></a>
-<span class="sourceLineNo">783</span><a name="line.783"></a>
-<span class="sourceLineNo">784</span>      return pickRandomRegions(cluster, thisServer, otherServer);<a name="line.784"></a>
-<span class="sourceLineNo">785</span>    }<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>  static class LoadCandidateGenerator extends CandidateGenerator {<a name="line.788"></a>
+<span class="sourceLineNo">781</span>      int thisServer = pickRandomServer(cluster);<a name="line.781"></a>
+<span class="sourceLineNo">782</span><a name="line.782"></a>
+<span class="sourceLineNo">783</span>      // Pick the other server<a name="line.783"></a>
+<span class="sourceLineNo">784</span>      int otherServer = pickOtherRandomServer(cluster, thisServer);<a name="line.784"></a>
+<span class="sourceLineNo">785</span><a name="line.785"></a>
+<span class="sourceLineNo">786</span>      return pickRandomRegions(cluster, thisServer, otherServer);<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><a name="line.789"></a>
-<span class="sourceLineNo">790</span>    @Override<a name="line.790"></a>
-<span class="sourceLineNo">791</span>    Cluster.Action generate(Cluster cluster) {<a name="line.791"></a>
-<span class="sourceLineNo">792</span>      cluster.sortServersByRegionCount();<a name="line.792"></a>
-<span class="sourceLineNo">793</span>      int thisServer = pickMostLoadedServer(cluster, -1);<a name="line.793"></a>
-<span class="sourceLineNo">794</span>      int otherServer = pickLeastLoadedServer(cluster, thisServer);<a name="line.794"></a>
-<span class="sourceLineNo">795</span><a name="line.795"></a>
-<span class="sourceLineNo">796</span>      return pickRandomRegions(cluster, thisServer, otherServer);<a name="line.796"></a>
-<span class="sourceLineNo">797</span>    }<a name="line.797"></a>
-<span class="sourceLineNo">798</span><a name="line.798"></a>
-<span class="sourceLineNo">799</span>    private int pickLeastLoadedServer(final Cluster cluster, int thisServer) {<a name="line.799"></a>
-<span class="sourceLineNo">800</span>      Integer[] servers = cluster.serverIndicesSortedByRegionCount;<a name="line.800"></a>
-<span class="sourceLineNo">801</span><a name="line.801"></a>
-<span class="sourceLineNo">802</span>      int index = 0;<a name="line.802"></a>
-<span class="sourceLineNo">803</span>      while (servers[index] == null || servers[index] == thisServer) {<a name="line.803"></a>
-<span class="sourceLineNo">804</span>        index++;<a name="line.804"></a>
-<span class="sourceLineNo">805</span>        if (index == servers.length) {<a name="line.805"></a>
-<span class="sourceLineNo">806</span>          return -1;<a name="line.806"></a>
-<span class="sourceLineNo">807</span>        }<a name="line.807"></a>
-<span class="sourceLineNo">808</span>      }<a name="line.808"></a>
-<span class="sourceLineNo">809</span>      return servers[index];<a name="line.809"></a>
-<span class="sourceLineNo">810</span>    }<a name="line.810"></a>
-<span class="sourceLineNo">811</span><a name="line.811"></a>
-<span class="sourceLineNo">812</span>    private int pickMostLoadedServer(final Cluster cluster, int thisServer) {<a name="line.812"></a>
-<span class="sourceLineNo">813</span>      Integer[] servers = cluster.serverIndicesSortedByRegionCount;<a name="line.813"></a>
-<span class="sourceLineNo">814</span><a name="line.814"></a>
-<span class="sourceLineNo">815</span>      int index = servers.length - 1;<a name="line.815"></a>
-<span class="sourceLineNo">816</span>      while (servers[index] == null || servers[index] == thisServer) {<a name="line.816"></a>
-<span class="sourceLineNo">817</span>        index--;<a name="line.817"></a>
-<span class="sourceLineNo">818</span>        if (index &lt; 0) {<a name="line.818"></a>
-<span class="sourceLineNo">819</span>          return -1;<a name="line.819"></a>
-<span class="sourceLineNo">820</span>        }<a name="line.820"></a>
-<span class="sourceLineNo">821</span>      }<a name="line.821"></a>
-<span class="sourceLineNo">822</span>      return servers[index];<a name="line.822"></a>
-<span class="sourceLineNo">823</span>    }<a name="line.823"></a>
-<span class="sourceLineNo">824</span>  }<a name="line.824"></a>
-<span class="sourceLineNo">825</span><a name="line.825"></a>
-<span class="sourceLineNo">826</span>  static class LocalityBasedCandidateGenerator extends CandidateGenerator {<a name="line.826"></a>
+<span class="sourceLineNo">790</span>  static class LoadCandidateGenerator extends CandidateGenerator {<a name="line.790"></a>
+<span class="sourceLineNo">791</span><a name="line.791"></a>
+<span class="sourceLineNo">792</span>    @Override<a name="line.792"></a>
+<span class="sourceLineNo">793</span>    Cluster.Action generate(Cluster cluster) {<a name="line.793"></a>
+<span class="sourceLineNo">794</span>      cluster.sortServersByRegionCount();<a name="line.794"></a>
+<span class="sourceLineNo">795</span>      int thisServer = pickMostLoadedServer(cluster, -1);<a name="line.795"></a>
+<span class="sourceLineNo">796</span>      int otherServer = pickLeastLoadedServer(cluster, thisServer);<a name="line.796"></a>
+<span class="sourceLineNo">797</span><a name="line.797"></a>
+<span class="sourceLineNo">798</span>      return pickRandomRegions(cluster, thisServer, otherServer);<a name="line.798"></a>
+<span class="sourceLineNo">799</span>    }<a name="line.799"></a>
+<span class="sourceLineNo">800</span><a name="line.800"></a>
+<span class="sourceLineNo">801</span>    private int pickLeastLoadedServer(final Cluster cluster, int thisServer) {<a name="line.801"></a>
+<span class="sourceLineNo">802</span>      Integer[] servers = cluster.serverIndicesSortedByRegionCount;<a name="line.802"></a>
+<span class="sourceLineNo">803</span><a name="line.803"></a>
+<span class="sourceLineNo">804</span>      int index = 0;<a name="line.804"></a>
+<span class="sourceLineNo">805</span>      while (servers[index] == null || servers[index] == thisServer) {<a name="line.805"></a>
+<span class="sourceLineNo">806</span>        index++;<a name="line.806"></a>
+<span class="sourceLineNo">807</span>        if (index == servers.length) {<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>      }<a name="line.810"></a>
+<span class="sourceLineNo">811</span>      return servers[index];<a name="line.811"></a>
+<span class="sourceLineNo">812</span>    }<a name="line.812"></a>
+<span class="sourceLineNo">813</span><a name="line.813"></a>
+<span class="sourceLineNo">814</span>    private int pickMostLoadedServer(final Cluster cluster, int thisServer) {<a name="line.814"></a>
+<span class="sourceLineNo">815</span>      Integer[] servers = cluster.serverIndicesSortedByRegionCount;<a name="line.815"></a>
+<span class="sourceLineNo">816</span><a name="line.816"></a>
+<span class="sourceLineNo">817</span>      int index = servers.length - 1;<a name="line.817"></a>
+<span class="sourceLineNo">818</span>      while (servers[index] == null || servers[index] == thisServer) {<a name="line.818"></a>
+<span class="sourceLineNo">819</span>        index--;<a name="line.819"></a>
+<span class="sourceLineNo">820</span>        if (index &lt; 0) {<a name="line.820"></a>
+<span class="sourceLineNo">821</span>          return -1;<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>      return servers[index];<a name="line.824"></a>
+<span class="sourceLineNo">825</span>    }<a name="line.825"></a>
+<span class="sourceLineNo">826</span>  }<a name="line.826"></a>
 <span class="sourceLineNo">827</span><a name="line.827"></a>
-<span class="sourceLineNo">828</span>    private MasterServices masterServices;<a name="line.828"></a>
+<span class="sourceLineNo">828</span>  static class LocalityBasedCandidateGenerator extends CandidateGenerator {<a name="line.828"></a>
 <span class="sourceLineNo">829</span><a name="line.829"></a>
-<span class="sourceLineNo">830</span>    LocalityBasedCandidateGenerator(MasterServices masterServices) {<a name="line.830"></a>
-<span class="sourceLineNo">831</span>      this.masterServices = masterServices;<a name="line.831"></a>
-<span class="sourceLineNo">832</span>    }<a name="line.832"></a>
-<span class="sourceLineNo">833</span><a name="line.833"></a>
-<span class="sourceLineNo">834</span>    @Override<a name="line.834"></a>
-<span class="sourceLineNo">835</span>    Cluster.Action generate(Cluster cluster) {<a name="line.835"></a>
-<span class="sourceLineNo">836</span>      if (this.masterServices == null) {<a name="line.836"></a>
-<span class="sourceLineNo">837</span>        int thisServer = pickRandomServer(cluster);<a name="line.837"></a>
-<span class="sourceLineNo">838</span>        // Pick the other server<a name="line.838"></a>
-<span class="sourceLineNo">839</span>        int otherServer = pickOtherRandomServer(cluster, thisServer);<a name="line.839"></a>
-<span class="sourceLineNo">840</span>        return pickRandomRegions(cluster, thisServer, otherServer);<a name="line.840"></a>
-<span class="sourceLineNo">841</span>      }<a name="line.841"></a>
-<span class="sourceLineNo">842</span><a name="line.842"></a>
-<span class="sourceLineNo">843</span>      // Randomly iterate through regions until you find one that is not on ideal host<a name="line.843"></a>
-<span class="sourceLineNo">844</span>      for (int region : getRandomIterationOrder(cluster.numRegions)) {<a name="line.844"></a>
-<span class="sourceLineNo">845</span>        int currentServer = cluster.regionIndexToServerIndex[region];<a name="line.845"></a>
-<span class="sourceLineNo">846</span>        if (currentServer != cluster.getOrComputeRegionsToMostLocalEntities(LocalityType.SERVER)[region]) {<a name="line.846"></a>
-<span class="sourceLineNo">847</span>          Optional&lt;Action&gt; potential = tryMoveOrSwap(<a name="line.847"></a>
-<span class="sourceLineNo">848</span>              cluster,<a name="line.848"></a>
-<span class="sourceLineNo">849</span>              currentServer,<a name="line.849"></a>
-<span class="sourceLineNo">850</span>              region,<a name="line.850"></a>
-<span class="sourceLineNo">851</span>              cluster.getOrComputeRegionsToMostLocalEntities(LocalityType.SERVER)[region]<a name="line.851"></a>
-<span class="sourceLineNo">852</span>          );<a name="line.852"></a>
-<span class="sourceLineNo">853</span>          if (potential.isPresent()) {<a name="line.853"></a>
-<span class="sourceLineNo">854</span>            return potential.get();<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>      }<a name="line.857"></a>
-<span class="sourceLineNo">858</span>      return Cluster.NullAction;<a name="line.858"></a>
-<span class="sourceLineNo">859</span>    }<a name="line.859"></a>
-<span class="sourceLineNo">860</span><a name="line.860"></a>
-<span class="sourceLineNo">861</span>    /**<a name="line.861"></a>
-<span class="sourceLineNo">862</span>     * Try to generate a move/swap fromRegion between fromServer and toServer such that locality is improved.<a name="line.862"></a>
-<span class="sourceLineNo">863</span>     * Returns empty optional if no move can be found<a name="line.863"></a>
-<span class="sourceLineNo">864</span>     */<a name="line.864"></a>
-<span class="sourceLineNo">865</span>    private Optional&lt;Action&gt; tryMoveOrSwap(Cluster cluster,<a name="line.865"></a>
-<span class="sourceLineNo">866</span>                                           int fromServer,<a name="line.866"></a>
-<span class="sourceLineNo">867</span>                                           int fromRegion,<a name="line.867"></a>
-<span class="sourceLineNo">868</span>                                           int toServer) {<a name="line.868"></a>
-<span class="sourceLineNo">869</span>      // Try move first. We know apriori fromRegion has the highest locality on toServer<a name="line.869"></a>
-<span class="sourceLineNo">870</span>      if (cluster.serverHasTooFewRegions(toServer)) {<a name="line.870"></a>
-<span class="sourceLineNo">871</span>        return Optional.of(getAction(fromServer, fromRegion, toServer, -1));<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>      // Compare locality gain/loss from swapping fromRegion with regions on toServer<a name="line.874"></a>
-<span class="sourceLineNo">875</span>      double fromRegionLocalityDelta =<a name="line.875"></a>
-<span class="sourceLineNo">876</span>          getWeightedLocality(cluster, fromRegion, toServer) - getWeightedLocality(cluster, fromRegion, fromServer);<a name="line.876"></a>
-<span class="sourceLineNo">877</span>      for (int toRegionIndex : getRandomIterationOrder(cluster.regionsPerServer[toServer].length)) {<a name="line.877"></a>
-<span class="sourceLineNo">878</span>        int toRegion = cluster.regionsPerServer[toServer][toRegionIndex];<a name="line.878"></a>
-<span class="sourceLineNo">879</span>        double toRegionLocalityDelta =<a name="line.879"></a>
-<span class="sourceLineNo">880</span>            getWeightedLocality(cluster, toRegion, fromServer) - getWeightedLocality(cluster, toRegion, toServer);<a name="line.880"></a>
-<span class="sourceLineNo">881</span>        // If locality would remain neutral or improve, attempt the swap<a name="line.881"></a>
-<span class="sourceLineNo">882</span>        if (fromRegionLocalityDelta + toRegionLocalityDelta &gt;= 0) {<a name="line.882"></a>
-<span class="sourceLineNo">883</span>          return Optional.of(getAction(fromServer, fromRegion, toServer, toRegion));<a name="line.883"></a>
-<span class="sourceLineNo">884</span>        }<a name="line.884"></a>
-<span class="sourceLineNo">885</span>      }<a name="line.885"></a>
-<span class="sourceLineNo">886</span><a name="line.886"></a>
-<span class="sourceLineNo">887</span>      return Optional.absent();<a name="line.887"></a>
-<span class="sourceLineNo">888</span>    }<a name="line.888"></a>
-<span class="sourceLineNo">889</span><a name="line.889"></a>
-<span class="sourceLineNo">890</span>    private double getWeightedLocality(Cluster cluster, int region, int server) {<a name="line.890"></a>
-<span class="sourceLineNo">891</span>      return cluster.getOrComputeWeightedLocality(region, server, LocalityType.SERVER);<a name="line.891"></a>
-<span class="sourceLineNo">892</span>    }<a name="line.892"></a>
-<span class="sourceLineNo">893</span><a name="line.893"></a>
-<span class="sourceLineNo">894</span>    void setServices(MasterServices services) {<a name="line.894"></a>
-<span class="sourceLineNo">895</span>      this.masterServices = services;<a name="line.895"></a>
-<span class="sourceLineNo">896</span>    }<a name="line.896"></a>
-<span class="sourceLineNo">897</span>  }<a name="line.897"></a>
-<span class="sourceLineNo">898</span><a name="line.898"></a>
-<span class="sourceLineNo">899</span>  /**<a name="line.899"></a>
-<span class="sourceLineNo">900</span>   * Generates candidates which moves the replicas out of the region server for<a name="line.900"></a>
-<span class="sourceLineNo">901</span>   * co-hosted region replicas<a name="line.901"></a>
-<span class="sourceLineNo">902</span>   */<a name="line.902"></a>
-<span class="sourceLineNo">903</span>  static class RegionReplicaCandidateGenerator extends CandidateGenerator {<a name="line.903"></a>
-<span class="sourceLineNo">904</span><a name="line.904"></a>
-<span class="sourceLineNo">905</span>    RandomCandidateGenerator randomGenerator = new RandomCandidateGenerator();<a name="line.905"></a>
+<span class="sourceLineNo">830</span>    private MasterServices masterServices;<a name="line.830"></a>
+<span class="sourceLineNo">831</span><a name="line.831"></a>
+<span class="sourceLineNo">832</span>    LocalityBasedCandidateGenerator(MasterServices masterServices) {<a name="line.832"></a>
+<span class="sourceLineNo">833</span>      this.masterServices = masterServices;<a name="line.833"></a>
+<span class="sourceLineNo">834</span>    }<a name="line.834"></a>
+<span class="sourceLineNo">835</span><a name="line.835"></a>
+<span class="sourceLineNo">836</span>    @Override<a name="line.836"></a>
+<span class="sourceLineNo">837</span>    Cluster.Action generate(Cluster cluster) {<a name="line.837"></a>
+<span class="sourceLineNo">838</span>      if (this.masterServices == null) {<a name="line.838"></a>
+<span class="sourceLineNo">839</span>        int thisServer = pickRandomServer(cluster);<a name="line.839"></a>
+<span class="sourceLineNo">840</span>        // Pick the other server<a name="line.840"></a>
+<span class="sourceLineNo">841</span>        int otherServer = pickOtherRandomServer(cluster, thisServer);<a name="line.841"></a>
+<span class="sourceLineNo">842</span>        return pickRandomRegions(cluster, thisServer, otherServer);<a name="line.842"></a>
+<span class="sourceLineNo">843</span>      }<a name="line.843"></a>
+<span class="sourceLineNo">844</span><a name="line.844"></a>
+<span class="sourceLineNo">845</span>      // Randomly iterate through regions until you find one that is not on ideal host<a name="line.845"></a>
+<span class="sourceLineNo">846</span>      for (int region : getRandomIterationOrder(cluster.numRegions)) {<a name="line.846"></a>
+<span class="sourceLineNo">847</span>        int currentServer = cluster.regionIndexToServerIndex[region];<a name="line.847"></a>
+<span class="sourceLineNo">848</span>        if (currentServer != cluster.getOrComputeRegionsToMostLocalEntities(LocalityType.SERVER)[region]) {<a name="line.848"></a>
+<span class="sourceLineNo">849</span>          Optional&lt;Action&gt; potential = tryMoveOrSwap(<a name="line.849"></a>
+<span class="sourceLineNo">850</span>              cluster,<a name="line.850"></a>
+<span class="sourceLineNo">851</span>              currentServer,<a name="line.851"></a>
+<span class="sourceLineNo">852</span>              region,<a name="line.852"></a>
+<span class="sourceLineNo">853</span>              cluster.getOrComputeRegionsToMostLocalEntities(LocalityType.SERVER)[region]<a name="line.853"></a>
+<span class="sourceLineNo">854</span>          );<a name="line.854"></a>
+<span class="sourceLineNo">855</span>          if (potential.isPresent()) {<a name="line.855"></a>
+<span class="sourceLineNo">856</span>            return potential.get();<a name="line.856"></a>
+<span class="sourceLineNo">857</span>          }<a name="line.857"></a>
+<span class="sourceLineNo">858</span>        }<a name="line.858"></a>
+<span class="sourceLineNo">859</span>      }<a name="line.859"></a>
+<span class="sourceLineNo">860</span>      return Cluster.NullAction;<a name="line.860"></a>
+<span class="sourceLineNo">861</span>    }<a name="line.861"></a>
+<span class="sourceLineNo">862</span><a name="line.862"></a>
+<span class="sourceLineNo">863</span>    /**<a name="line.863"></a>
+<span class="sourceLineNo">864</span>     * Try to generate a move/swap fromRegion between fromServer and toServer such that locality is improved.<a name="line.864"></a>
+<span class="sourceLineNo">865</span>     * Returns empty optional if no move can be found<a name="line.865"></a>
+<span class="sourceLineNo">866</span>     */<a name="line.866"></a>
+<span class="sourceLineNo">867</span>    private Optional&lt;Action&gt; tryMoveOrSwap(Cluster cluster,<a name="line.867"></a>
+<span class="sourceLineNo">868</span>                                           int fromServer,<a name="line.868"></a>
+<span class="sourceLineNo">869</span>                                           int fromRegion,<a name="line.869"></a>
+<span class="sourceLineNo">870</span>                                           int toServer) {<a name="line.870"></a>
+<span class="sourceLineNo">871</span>      // Try move first. We know apriori fromRegion has the highest locality on toServer<a name="line.871"></a>
+<span class="sourceLineNo">872</span>      if (cluster.serverHasTooFewRegions(toServer)) {<a name="line.872"></a>
+<span class="sourceLineNo">873</span>        return Optional.of(getAction(fromServer, fromRegion, toServer, -1));<a name="line.873"></a>
+<span class="sourceLineNo">874</span>      }<a name="line.874"></a>
+<span class="sourceLineNo">875</span><a name="line.875"></a>
+<span class="sourceLineNo">876</span>      // Compare locality gain/loss from swapping fromRegion with regions on toServer<a name="line.876"></a>
+<span class="sourceLineNo">877</span>      double fromRegionLocalityDelta =<a name="line.877"></a>
+<span class="sourceLineNo">878</span>          getWeightedLocality(cluster, fromRegion, toServer) - getWeightedLocality(cluster, fromRegion, fromServer);<a name="line.878"></a>
+<span class="sourceLineNo">879</span>      for (int toRegionIndex : getRandomIterationOrder(cluster.regionsPerServer[toServer].length)) {<a name="line.879"></a>
+<span class="sourceLineNo">880</span>        int toRegion = cluster.regionsPerServer[toServer][toRegionIndex];<a name="line.880"></a>
+<span class="sourceLineNo">881</span>        double toRegionLocalityDelta =<a name="line.881"></a>
+<span class="sourceLineNo">882</span>            getWeightedLocality(cluster, toRegion, fromServer) - getWeightedLocality(cluster, toRegion, toServer);<a name="line.882"></a>
+<span class="sourceLineNo">883</span>        // If locality would remain neutral or improve, attempt the swap<a name="line.883"></a>
+<span class="sourceLineNo">884</span>        if (fromRegionLocalityDelta + toRegionLocalityDelta &gt;= 0) {<a name="line.884"></a>
+<span class="sourceLineNo">885</span>          return Optional.of(getAction(fromServer, fromRegion, toServer, toRegion));<a name="line.885"></a>
+<span class="sourceLineNo">886</span>        }<a name="line.886"></a>
+<span class="sourceLineNo">887</span>      }<a name="line.887"></a>
+<span class="sourceLineNo">888</span><a name="line.888"></a>
+<span class="sourceLineNo">889</span>      return Optional.absent();<a name="line.889"></a>
+<span class="sourceLineNo">890</span>    }<a name="line.890"></a>
+<span class="sourceLineNo">891</span><a name="line.891"></a>
+<span class="sourceLineNo">892</span>    private double getWeightedLocality(Cluster cluster, int region, int server) {<a name="line.892"></a>
+<span class="sourceLineNo">893</span>      return cluster.getOrComputeWeightedLocality(region, server, LocalityType.SERVER);<a name="line.893"></a>
+<span class="sourceLineNo">894</span>    }<a name="line.894"></a>
+<span class="sourceLineNo">895</span><a name="line.895"></a>
+<span class="sourceLineNo">896</span>    void setServices(MasterServices services) {<a name="line.896"></a>
+<span class="sourceLineNo">897</span>      this.masterServices = services;<a name="line.897"></a>
+<span class="sourceLineNo">898</span>    }<a name="line.898"></a>
+<span class="sourceLineNo">899</span>  }<a name="line.899"></a>
+<span class="sourceLineNo">900</span><a name="line.900"></a>
+<span class="sourceLineNo">901</span>  /**<a name="line.901"></a>
+<span class="sourceLineNo">902</span>   * Generates candidates which moves the replicas out of the region server for<a name="line.902"></a>
+<span class="sourceLineNo">903</span>   * co-hosted region replicas<a name="line.903"></a>
+<span class="sourceLineNo">904</span>   */<a name="line.904"></a>
+<span class="sourceLineNo">905</span>  static class RegionReplicaCandidateGenerator extends CandidateGenerator {<a name="line.905"></a>
 <span class="sourceLineNo">906</span><a name="line.906"></a>
-<span class="sourceLineNo">907</span>    /**<a name="line.907"></a>
-<span class="sourceLineNo">908</span>     * Randomly select one regionIndex out of all region replicas co-hosted in the same group<a name="line.908"></a>
-<span class="sourceLineNo">909</span>     * (a group is a server, host or rack)<a name="line.909"></a>
-<span class="sourceLineNo">910</span>     * @param primariesOfRegionsPerGroup either Cluster.primariesOfRegionsPerServer,<a name="line.910"></a>
-<span class="sourceLineNo">911</span>     * primariesOfRegionsPerHost or primariesOfRegionsPerRack<a name="line.911"></a>
-<span class="sourceLineNo">912</span>     * @param regionsPerGroup either Cluster.regionsPerServer, regionsPerHost or regionsPerRack<a name="line.912"></a>
-<span class="sourceLineNo">913</span>     * @param regionIndexToPrimaryIndex Cluster.regionsIndexToPrimaryIndex<a name="line.913"></a>
-<span class="sourceLineNo">914</span>     * @return a regionIndex for the selected primary or -1 if there is no co-locating<a name="line.914"></a>
-<span class="sourceLineNo">915</span>     */<a name="line.915"></a>
-<span class="sourceLineNo">916</span>    int selectCoHostedRegionPerGroup(int[] primariesOfRegionsPerGroup, int[] regionsPerGroup<a name="line.916"></a>
-<span class="sourceLineNo">917</span>        , int[] regionIndexToPrimaryIndex) {<a name="line.917"></a>
-<span class="sourceLineNo">918</span>      int currentPrimary = -1;<a name="line.918"></a>
-<span class="sourceLineNo">919</span>      int currentPrimaryIndex = -1;<a name="line.919"></a>
-<span class="sourceLineNo">920</span>      int selectedPrimaryIndex = -1;<a name="line.920"></a>
-<span class="sourceLineNo">921</span>      double currentLargestRandom = -1;<a name="line.921"></a>
-<span class="sourceLineNo">922</span>      // primariesOfRegionsPerGroup is a sorted array. Since it contains the primary region<a name="line.922"></a>
-<span class="sourceLineNo">923</span>      // ids for the regions hosted in server, a consecutive repetition means that replicas<a name="line.923"></a>
-<span class="sourceLineNo">924</span>      // are co-hosted<a name="line.924"></a>
-<span class="sourceLineNo">925</span>      for (int j = 0; j &lt;= primariesOfRegionsPerGroup.length; j++) {<a name="line.925"></a>
-<span class="sourceLineNo">926</span>        int primary = j &lt; primariesOfRegionsPerGroup.length<a name="line.926"></a>
-<span class="sourceLineNo">927</span>            ? primariesOfRegionsPerGroup[j] : -1;<a name="line.927"></a>
-<span class="sourceLineNo">928</span>        if (primary != currentPrimary) { // check for whether we see a new primary<a name="line.928"></a>
-<span class="sourceLineNo">929</span>          int numReplicas = j - currentPrimaryIndex;<a name="line.929"></a>
-<span class="sourceLineNo">930</span>          if (numReplicas &gt; 1) { // means consecutive primaries, indicating co-location<a name="line.930"></a>
-<span class="sourceLineNo">931</span>            // decide to select this primary region id or not<a name="line.931"></a>
-<span class="sourceLineNo">932</span>            double currentRandom = RANDOM.nextDouble();<a name="line.932"></a>
-<span class="sourceLineNo">933</span>            // we don't know how many region replicas are co-hosted, we will randomly select one<a name="line.933"></a>
-<span class="sourceLineNo">934</span>            // using reservoir sampling (http://gregable.com/2007/10/reservoir-sampling.html)<a name="line.934"></a>
-<span class="sourceLineNo">935</span>            if (currentRandom &gt; currentLargestRandom) {<a name="line.935"></a>
-<span class="sourceLineNo">936</span>              selectedPrimaryIndex = currentPrimary;<a name="line.936"></a>
-<span class="sourceLineNo">937</span>              currentLargestRandom = currentRandom;<a name="line.937"></a>
-<span class="sourceLineNo">938</span>            }<a name="line.938"></a>
-<span class="sourceLineNo">939</span>          }<a name="line.939"></a>
-<span class="sourceLineNo">940</span>          currentPrimary = primary;<a name="line.940"></a>
-<span class="sourceLineNo">941</span>          currentPrimaryIndex = j;<a name="line.941"></a>
-<span class="sourceLineNo">942</span>        }<a name="line.942"></a>
-<span class="sourceLineNo">943</span>      }<a name="line.943"></a>
-<span class="sourceLineNo">944</span><a name="line.944"></a>
-<span class="sourceLineNo">945</span>      // we have found the primary id for the region to move. Now find the actual regionIndex<a name="line.945"></a>
-<span class="sourceLineNo">946</span>      // with the given primary, prefer to move the secondary region.<a name="line.946"></a>
-<span class="sourceLineNo">947</span>      for (int j = 0; j &lt; regionsPerGroup.length; j++) {<a name="line.947"></a>
-<span class="sourceLineNo">948</span>        int regionIndex = regionsPerGroup[j];<a name="line.948"></a>
-<span class="sourceLineNo">949</span>        if (selectedPrimaryIndex == regionIndexToPrimaryIndex[regionIndex]) {<a name="line.949"></a>
-<span class="sourceLineNo">950</span>          // always move the secondary, not the primary<a name="line.950"></a>
-<span class="sourceLineNo">951</span>          if (selectedPrimaryIndex != regionIndex) {<a name="line.951"></a>
-<span class="sourceLineNo">952</span>            return regionIndex;<a name="line.952"></a>
-<span class="sourceLineNo">953</span>          }<a name="line.953"></a>
-<span class="sourceLineNo">954</span>        }<a name="line.954"></a>
-<span class="sourceLineNo">955</span>      }<a name="line.955"></a>
-<span class="sourceLineNo">956</span>      return -1;<a name="line.956"></a>
-<span class="sourceLineNo">957</span>    }<a name="line.957"></a>
-<span class="sourceLineNo">958</span><a name="line.958"></a>
-<span class="sourceLineNo">959</span>    @Override<a name="line.959"></a>
-<span class="sourceLineNo">960</span>    Cluster.Action generate(Cluster cluster) {<a name="line.960"></a>
-<span class="sourceLineNo">961</span>      int serverIndex = pickRandomServer(cluster);<a name="line.961"></a>
-<span class="sourceLineNo">962</span>      if (cluster.numServers &lt;= 1 || serverIndex == -1) {<a name="line.962"></a>
-<span class="sourceLineNo">963</span>        return Cluster.NullAction;<a name="line.963"></a>
-<span class="sourceLineNo">964</span>      }<a name="line.964"></a>
-<span class="sourceLineNo">965</span><a name="line.965"></a>
-<span class="sourceLineNo">966</span>      int regionIndex = selectCoHostedRegionPerGroup(<a name="line.966"></a>
-<span class="sourceLineNo">967</span>        cluster.primariesOfRegionsPerServer[serverIndex],<a name="line.967"></a>
-<span class="sourceLineNo">968</span>        cluster.regionsPerServer[serverIndex],<a name="line.968"></a>
-<span class="sourceLineNo">969</span>        cluster.regionIndexToPrimaryIndex);<a name="line.969"></a>
-<span class="sourceLineNo">970</span><a name="line.970"></a>
-<span class="sourceLineNo">971</span>      // if there are no pairs of region replicas co-hosted, default to random generator<a name="line.971"></a>
-<span class="sourceLineNo">972</span>      if (regionIndex == -1) {<a name="line.972"></a>
-<span class="sourceLineNo">973</span>        // default to randompicker<a name="line.973"></a>
-<span class="sourceLineNo">974</span>        return randomGenerator.generate(cluster);<a name="line.974"></a>
-<span class="sourceLineNo">975</span>      }<a name="line.975"></a>
-<span class="sourceLineNo">976</span><a name="line.976"></a>
-<span class="sourceLineNo">977</span>      int toServerIndex = pickOtherRandomServer(cluster, serverIndex);<a name="line.977"></a>
-<span class="sourceLineNo">978</span>      int toRegionIndex = pickRandomRegion(cluster, toServerIndex, 0.9f);<a name="line.978"></a>
-<span class="sourceLineNo">979</span>      return getAction(serverIndex, regionIndex, toServerIndex, toRegionIndex);<a name="line.979"></a>
-<span class="sourceLineNo">980</span>    }<a name="line.980"></a>
-<span class="sourceLineNo">981</span>  }<a name="line.981"></a>
-<span class="sourceLineNo">982</span><a name="line.982"></a>
-<span class="sourceLineNo">983</span>  /**<a name="line.983"></a>
-<span class="sourceLineNo">984</span>   * Generates candidates which moves the replicas out of the rack for<a name="line.984"></a>
-<span class="sourceLineNo">985</span>   * co-hosted region replicas in the same rack<a name="line.985"></a>
-<span class="sourceLineNo">986</span>   */<a name="line.986"></a>
-<span class="sourceLineNo">987</span>  static class RegionReplicaRackCandidateGenerator extends RegionReplicaCandidateGenerator {<a name="line.987"></a>
-<span class="sourceLineNo">988</span>    @Override<a name="line.988"></a>
-<span class="sourceLineNo">989</span>    Cluster.Action generate(Cluster cluster) {<a name="line.989"></a>
-<span class="sourceLineNo">990</span>      int rackIndex = pickRandomRack(cluster);<a name="line.990"></a>
-<span class="sourceLineNo">991</span>      if (cluster.numRacks &lt;= 1 || rackIndex == -1) {<a name="line.991"></a>
-<span class="sourceLineNo">992</span>        return super.generate(cluster);<a name="line.992"></a>
-<span class="sourceLineNo">993</span>      }<a name="line.993"></a>
-<span class="sourceLineNo">994</span><a name="line.994"></a>
-<span class="sourceLineNo">995</span>      int regionIndex = selectCoHostedRegionPerGroup(<a name="line.995"></a>
-<span class="sourceLineNo">996</span>        cluster.primariesOfRegionsPerRack[rackIndex],<a name="line.996"></a>
-<span class="sourceLineNo">997</span>        cluster.regionsPerRack[rackIndex],<a name="line.997"></a>
-<span class="sourceLineNo">998</span>        cluster.regionIndexToPrimaryIndex);<a name="line.998"></a>
-<span class="sourceLineNo">999</span><a name="line.999"></a>
-<span class="sourceLineNo">1000</span>      // if there are no pairs of region replicas co-hosted, default to random generator<a name="line.1000"></a>
-<span class="sourceLineNo">1001</span>      if (regionIndex == -1) {<a name="line.1001"></a>
-<span class="sourceLineNo">1002</span>        // default to randompicker<a name="line.1002"></a>
-<span class="sourceLineNo">1003</span>        return randomGenerator.generate(cluster);<a name="line.1003"></a>
-<span class="sourceLineNo">1004</span>      }<a name="line.1004"></a>
-<span class="sourceLineNo">1005</span><a name="line.1005"></a>
-<span class="sourceLineNo">1006</span>      int serverIndex = cluster.regionIndexToServerIndex[regionIndex];<a name="line.1006"></a>
-<span class="sourceLineNo">1007</span>      int toRackIndex = pickOtherRandomRack(cluster, rackIndex);<a name="line.1007"></a>
-<span class="sourceLineNo">1008</span><a name="line.1008"></a>
-<span class="sourceLineNo">1009</span>      int rand = RANDOM.nextInt(cluster.serversPerRack[toRackIndex].length);<a name="line.1009"></a>
-<span class="sourceLineNo">1010</span>      int toServerIndex = cluster.serversPerRack[toRackIndex][rand];<a name="line.1010"></a>
-<span class="sourceLineNo">1011</span>      int toRegionIndex = pickRandomRegion(cluster, toServerIndex, 0.9f);<a name="line.1011"></a>
-<span class="sourceLineNo">1012</span>      return getAction(serverIndex, regionIndex, toServerIndex, toRegionIndex);<a name="line.1012"></a>
-<span class="sourceLineNo">1013</span>    }<a name="line.1013"></a>
-<span class="sourceLineNo">1014</span>  }<a name="line.1014"></a>
-<span class="sourceLineNo">1015</span><a name="line.1015"></a>
-<span class="sourceLineNo">1016</span>  /**<a name="line.1016"></a>
-<span class="sourceLineNo">1017</span>   * Base class of StochasticLoadBalancer's Cost Functions.<a name="line.1017"></a>
-<span class="sourceLineNo">1018</span>   */<a name="line.1018"></a>
-<span class="sourceLineNo">1019</span>  public abstract static class CostFunction {<a name="line.1019"></a>
-<span class="sourceLineNo">1020</span><a name="line.1020"></a>
-<span class="sourceLineNo">1021</span>    private float multiplier = 0;<a name="line.1021"></a>
+<span class="sourceLineNo">907</span>    RandomCandidateGenerator randomGenerator = new RandomCandidateGenerator();<a name="line.907"></a>
+<span class="sourceLineNo">908</span><a name="line.908"></a>
+<span class="sourceLineNo">909</span>    /**<a name="line.909"></a>
+<span class="sourceLineNo">910</span>     * Randomly select one regionIndex out of all region replicas co-hosted in the same group<a name="line.910"></a>
+<span class="sourceLineNo">911</span>     * (a group is a server, host or rack)<a name="line.911"></a>
+<span class="sourceLineNo">912</span>     * @param primariesOfRegionsPerGroup either Cluster.primariesOfRegionsPerServer,<a name="line.912"></a>
+<span class="sourceLineNo">913</span>     * primariesOfRegionsPerHost or primariesOfRegionsPerRack<a name="line.913"></a>
+<span class="sourceLineNo">914</span>     * @param regionsPerGroup either Cluster.regionsPerServer, regionsPerHost or regionsPerRack<a name="line.914"></a>
+<span class="sourceLineNo">915</span>     * @param regionIndexToPrimaryIndex Cluster.regionsIndexToPrimaryIndex<a name="line.915"></a>
+<span class="sourceLineNo">916</span>     * @return a regionIndex for the selected primary or -1 if there is no co-locating<a name="line.916"></a>
+<span class="sourceLineNo">917</span>     */<a name="line.917"></a>
+<span class="sourceLineNo">918</span>    int selectCoHostedRegionPerGroup(int[] primariesOfRegionsPerGroup, int[] regionsPerGroup<a name="line.918"></a>
+<span class="sourceLineNo">919</span>        , int[] regionIndexToPrimaryIndex) {<a name="line.919"></a>
+<span class="sourceLineNo">920</span>      int currentPrimary = -1;<a name="line.920"></a>
+<span class="sourceLineNo">921</span>      int currentPrimaryIndex = -1;<a name="line.921"></a>
+<span class="sourceLineNo">922</span>      int selectedPrimaryIndex = -1;<a name="line.922"></a>
+<span class="sourceLineNo">923</span>      double currentLargestRandom = -1;<a name="line.923"></a>
+<span class="sourceLineNo">924</span>      // primariesOfRegionsPerGroup is a sorted array. Since it contains the primary region<a name="line.924"></a>
+<span class="sourceLineNo">925</span>      // ids for the regions hosted in server, a consecutive repetition means that replicas<a name="line.925"></a>
+<span class="sourceLineNo">926</span>      // are co-hosted<a name="line.926"></a>
+<span class="sourceLineNo">927</span>      for (int j = 0; j &lt;= primariesOfRegionsPerGroup.length; j++) {<a name="line.927"></a>
+<span class="sourceLineNo">928</span>        int primary = j &lt; primariesOfRegionsPerGroup.length<a name="line.928"></a>
+<span class="sourceLineNo">929</span>            ? primariesOfRegionsPerGroup[j] : -1;<a name="line.929"></a>
+<span class="sourceLineNo">930</span>        if (primary != currentPrimary) { // check for whether we see a new primary<a name="line.930"></a>
+<span class="sourceLineNo">931</span>          int numReplicas = j - currentPrimaryIndex;<a name="line.931"></a>
+<span class="sourceLineNo">932</span>          if (numReplicas &gt; 1) { // means consecutive primaries, indicating co-location<a name="line.932"></a>
+<span class="sourceLineNo">933</span>            // decide to select this primary region id or not<a name="line.933"></a>
+<span class="sourceLineNo">934</span>            double currentRandom = RANDOM.nextDouble();<a name="line.934"></a>
+<span class="sourceLineNo">935</span>            // we don't know how many region replicas are co-hosted, we will randomly select one<a name="line.935"></a>
+<span class="sourceLineNo">936</span>            // using reservoir sampling (http://gregable.com/2007/10/reservoir-sampling.html)<a name="line.936"></a>
+<span class="sourceLineNo">937</span>            if (currentRandom &gt; currentLargestRandom) {<a name="line.937"></a>
+<span class="sourceLineNo">938</span>              selectedPrimaryIndex = currentPrimary;<a name="line.938"></a>
+<span class="sourceLineNo">939</span>              currentLargestRandom = currentRandom;<a name="line.939"></a>
+<span class="sourceLineNo">940</span>            }<a name="line.940"></a>
+<span class="sourceLineNo">941</span>          }<a name="line.941"></a>
+<span class="sourceLineNo">942</span>          currentPrimary = primary;<a name="line.942"></a>
+<span class="sourceLineNo">943</span>          currentPrimaryIndex = j;<a name="line.943"></a>
+<span class="sourceLineNo">944</span>        }<a name="line.944"></a>
+<span class="sourceLineNo">945</span>      }<a name="line.945"></a>
+<span class="sourceLineNo">946</span><a name="line.946"></a>
+<span class="sourceLineNo">947</span>      // we have found the primary id for the region to move. Now find the actual regionIndex<a name="line.947"></a>
+<span class="sourceLineNo">948</span>      // with the given primary, prefer to move the secondary region.<a name="line.948"></a>
+<span class="sourceLineNo">949</span>      for (int j = 0; j &lt; regionsPerGroup.length; j++) {<a name="line.949"></a>
+<span class="sourceLineNo">950</span>        int regionIndex = regionsPerGroup[j];<a name="line.950"></a>
+<span class="sourceLineNo">951</span>        if (selectedPrimaryIndex == regionIndexToPrimaryIndex[regionIndex]) {<a name="line.951"></a>
+<span class="sourceLineNo">952</span>          // always move the secondary, not the primary<a name="line.952"></a>
+<span class="sourceLineNo">953</span>          if (selectedPrimaryIndex != regionIndex) {<a name="line.953"></a>
+<span class="sourceLineNo">954</span>            return regionIndex;<a name="line.954"></a>
+<span class="sourceLineNo">955</span>          }<a name="line.955"></a>
+<span class="sourceLineNo">956</span>        }<a name="line.956"></a>
+<span class="sourceLineNo">957</span>      }<a name="line.957"></a>
+<span class="sourceLineNo">958</span>      return -1;<a name="line.958"></a>
+<span class="sourceLineNo">959</span>    }<a name="line.959"></a>
+<span class="sourceLineNo">960</span><a name="line.960"></a>
+<span class="sourceLineNo">961</span>    @Override<a name="line.961"></a>
+<span class="sourceLineNo">962</span>    Cluster.Action generate(Cluster cluster) {<a name="line.962"></a>
+<span class="sourceLineNo">963</span>      int serverIndex = pickRandomServer(cluster);<a name="line.963"></a>
+<span class="sourceLineNo">964</span>      if (cluster.numServers &lt;= 1 || serverIndex == -1) {<a name="line.964"></a>
+<span class="sourceLineNo">965</span>        return Cluster.NullAction;<a name="line.965"></a>
+<span class="sourceLineNo">966</span>      }<a name="line.966"></a>
+<span class="sourceLineNo">967</span><a name="line.967"></a>
+<span class="sourceLineNo">968</span>      int regionIndex = selectCoHostedRegionPerGroup(<a name="line.968"></a>
+<span class="sourceLineNo">969</span>        cluster.primariesOfRegionsPerServer[serverIndex],<a name="line.969"></a>
+<span class="sourceLineNo">970</span>        cluster.regionsPerServer[serverIndex],<a name="line.970"></a>
+<span class="sourceLineNo">971</span>        cluster.regionIndexToPrimaryIndex);<a name="line.971"></a>
+<span class="sourceLineNo">972</span><a name="line.972"></a>
+<span class="sourceLineNo">973</span>      // if there are no pairs of region replicas co-hosted, default to random generator<a name="line.973"></a>
+<span class="sourceLineNo">974</span>      if (regionIndex == -1) {<a name="line.974"></a>
+<span class="sourceLineNo">975</span>        // default to randompicker<a name="line.975"></a>
+<span class="sourceLineNo">976</span>        return randomGenerator.generate(cluster);<a name="line.976"></a>
+<span class="sourceLineNo">977</span>      }<a name="line.977"></a>
+<span class="sourceLineNo">978</span><a name="line.978"></a>
+<span class="sourceLineNo">979</span>      int toServerIndex = pickOtherRandomServer(cluster, serverIndex);<a name="line.979"></a>
+<span class="sourceLineNo">980</span>      int toRegionIndex = pickRandomRegion(cluster, toServerIndex, 0.9f);<a name="line.980"></a>
+<span class="sourceLineNo">981</span>      return getAction(serverIndex, regionIndex, toServerIndex, toRegionIndex);<a name="line.981"></a>
+<span class="sourceLineNo">982</span>    }<a name="line.982"></a>
+<span class="sourceLineNo">983</span>  }<a name="line.983"></a>
+<span class="sourceLineNo">984</span><a name="line.984"></a>
+<span class="sourceLineNo">985</span>  /**<a name="line.985"></a>
+<span class="sourceLineNo">986</span>   * Generates candidates which moves the replicas out of the rack for<a name="line.986"></a>
+<span class="sourceLineNo">987</span>   * co-hosted region replicas in the same rack<a name="line.987"></a>
+<span class="sourceLineNo">988</span>   */<a name="line.988"></a>
+<span class="sourceLineNo">989</span>  static class RegionReplicaRackCandidateGenerator extends RegionReplicaCandidateGenerator {<a name="line.989"></a>
+<span class="sourceLineNo">990</span>    @Override<a name="line.990"></a>
+<span class="sourceLineNo">991</span>    Cluster.Action generate(Cluster cluster) {<a name="line.991"></a>
+<span class="sourceLineNo">992</span>      int rackIndex = pickRandomRack(cluster);<a name="line.992"></a>
+<span class="sourceLineNo">993</span>      if (cluster.numRacks &lt;= 1 || rackIndex == -1) {<a name="line.993"></a>
+<span class="sourceLineNo">994</span>        return super.generate(cluster);<a name="line.994"></a>
+<span class="sourceLineNo">995</span>      }<a name="line.995"></a>
+<span class="sourceLineNo">996</span><a name="line.996"></a>
+<span class="sourceLineNo">997</span>      int regionIndex = selectCoHostedRegionPerGroup(<a name="line.997"></a>
+<span class="sourceLineNo">998</span>        cluster.primariesOfRegionsPerRack[rackIndex],<a name="line.998"></a>
+<span class="sourceLineNo">999</span>        cluster.regionsPerRack[rackIndex],<a name="line.999"></a>
+<span class="sourceLineNo">1000</span>        cluster.regionIndexToPrimaryIndex);<a name="line.1000"></a>
+<span class="sourceLineNo">1001</span><a name="line.1001"></a>
+<span class="sourceLineNo">1002</span>      // if there are no pairs of region replicas co-hosted, default to random generator<a name="line.1002"></a>
+<span class="sourceLineNo">1003</span>      if (regionIndex == -1) {<a name="line.1003"></a>
+<span class="sourceLineNo">1004</span>        // default to randompicker<a name="line.1004"></a>
+<span class="sourceLineNo">1005</span>        return randomGenerator.generate(cluster);<a name="line.1005"></a>
+<span class="sourceLineNo">1006</span>      }<a name="line.1006"></a>
+<span class="sourceLineNo">1007</span><a name="line.1007"></a>
+<span class="sourceLineNo">1008</span>      int serverIndex = cluster.regionIndexToServerIndex[regionIndex];<a name="line.1008"></a>
+<span class="sourceLineNo">1009</span>      int toRackIndex = pickOtherRandomRack(cluster, rackIndex);<a name="line.1009"></a>
+<span class="sourceLineNo">1010</span><a name="line.1010"></a>
+<span class="sourceLineNo">1011</span>      int rand = RANDOM.nextInt(cluster.serversPerRack[toRackIndex].length);<a name="line.1011"></a>
+<span class="sourceLineNo">1012</span>      int toServerIndex = cluster.serversPerRack[toRackIndex][rand];<a name="line.1012"></a>
+<span class="sourceLineNo">1013</span>      int toRegionIndex = pickRandomRegion(cluster, toServerIndex, 0.9f);<a name="line.1013"></a>
+<span class="sourceLineNo">1014</span>      return getAction(serverIndex, regionIndex, toServerIndex, toRegionIndex);<a name="line.1014"></a>
+<span class="sourceLineNo">1015</span>    }<a name="line.1015"></a>
+<span class="sourceLineNo">1016</span>  }<a name="line.1016"></a>
+<span class="sourceLineNo">1017</span><a name="line.1017"></a>
+<span class="sourceLineNo">1018</span>  /**<a name="line.1018"></a>
+<span class="sourceLineNo">1019</span>   * Base class of StochasticLoadBalancer's Cost Functions.<a name="line.1019"></a>
+<span class="sourceLineNo">1020</span>   */<a name="line.1020"></a>
+<span class="sourceLineNo">1021</span>  public abstract static class CostFunction {<a name="line.1021"></a>
 <span class="sourceLineNo">1022</span><a name="line.1022"></a>
-<span class="sourceLineNo">1023</span>    protected Cluster cluster;<a name="line.1023"></a>
+<span class="sourceLineNo">1023</span>    private float multiplier = 0;<a name="line.1023"></a>
 <span class="sourceLineNo">1024</span><a name="line.1024"></a>
-<span class="sourceLineNo">1025</span>    public CostFunction(Configuration c) {<a name="line.1025"></a>
-<span class="sourceLineNo">1026</span>    }<a name="line.1026"></a>
-<span class="sourceLineNo">1027</span><a name="line.1027"></a>
-<span class="sourceLineNo">1028</span>    boolean isNeeded() {<a name="line.1028"></a>
-<span class="sourceLineNo">1029</span>      return true;<a name="line.1029"></a>
-<span class="sourceLineNo">1030</span>    }<a name="line.1030"></a>
-<span class="sourceLineNo">1031</span>    float getMultiplier() {<a name="line.1031"></a>
-<span class="sourceLineNo">1032</span>      return multiplier;<a name="line.1032"></a>
-<span class="sourceLineNo">1033</span>    }<a name="line.1033"></a>
-<span class="sourceLineNo">1034</span><a name="line.1034"></a>
-<span class="sourceLineNo">1035</span>    void setMultiplier(float m) {<a name="line.1035"></a>
-<span class="sourceLineNo">1036</span>      this.multiplier = m;<a name="line.1036"></a>
-<span class="sourceLineNo">1037</span>    }<a name="line.1037"></a>
-<span class="sourceLineNo">1038</span><a name="line.1038"></a>
-<span class="sourceLineNo">1039</span>    /** Called once per LB invocation to give the cost function<a name="line.1039"></a>
-<span class="sourceLineNo">1040</span>     * to initialize it's state, and perform any costly calculation.<a name="line.1040"></a>
-<span class="sourceLineNo">1041</span>     */<a name="line.1041"></a>
-<span class="sourceLineNo">1042</span>    void init(Cluster cluster) {<a name="line.1042"></a>
-<span class="sourceLineNo">1043</span>      this.cluster = cluster;<a name="line.1043"></a>
-<span class="sourceLineNo">1044</span>    }<a name="line.1044"></a>
-<span class="sourceLineNo">1045</span><a name="line.1045"></a>
-<span class="sourceLineNo">1046</span>    /** Called once per cluster Action to give the cost function<a name="line.1046"></a>
-<span class="sourceLineNo">1047</span>     * an opportunity to update it's state. postAction() is always<a name="line.1047"></a>
-<span class="sourceLineNo">1048</span>     * called at least once before cost() is called with the cluster<a name="line.1048"></a>
-<span class="sourceLineNo">1049</span>     * that this action is performed on. */<a name="line.1049"></a>
-<span class="sourceLineNo">1050</span>    void postAction(Action action) {<a name="line.1050"></a>
-<span class="sourceLineNo">1051</span>      switch (action.type) {<a name="line.1051"></a>
-<span class="sourceLineNo">1052</span>      case NULL: break;<a name="line.1052"></a>
-<span class="sourceLineNo">1053</span>      case ASSIGN_REGION:<a name="line.1053"></a>
-<span class="sourceLineNo">1054</span>        AssignRegionAction ar = (AssignRegionAction) action;<a name="line.1054"></a>
-<span class="sourceLineNo">1055</span>        regionMoved(ar.region, -1, ar.server);<a name="line.1055"></a>
-<span class="sourceLineNo">1056</span>        break;<a name="line.1056"></a>
-<span class="sourceLineNo">1057</span>      case MOVE_REGION:<a name="line.1057"></a>
-<span class="sourceLineNo">1058</span>        MoveRegionAction mra = (MoveRegionAction) action;<a name="line.1058"></a>
-<span class="sourceLineNo">1059</span>        regionMoved(mra.region, mra.fromServer, mra.toServer);<a name="line.1059"></a>
-<span class="sourceLineNo">1060</span>        break;<a name="line.1060"></a>
-<span class="sourceLineNo">1061</span>      case SWAP_REGIONS:<a name="line.1061"></a>
-<span class="sourceLineNo">1062</span>        SwapRegionsAction a = (SwapRegionsAction) action;<a name="line.1062"></a>
-<span class="sourceLineNo">1063</span>        regionMoved(a.fromRegion, a.fromServer, a.toServer);<a name="line.1063"></a>
-<span class="sourceLineNo">1064</span>        regionMoved(a.toRegion, a.toServer, a.fromServer);<a name="line.1064"></a>
-<span class="sourceLineNo">1065</span>        break;<a name="line.1065"></a>
-<span class="sourceLineNo">1066</span>      default:<a name="line.1066"></a>
-<span class="sourceLineNo">1067</span>        throw new RuntimeException("Uknown action:" + action.type);<a name="line.1067"></a>
-<span class="sourceLineNo">1068</span>      }<a name="line.1068"></a>
-<span class="sourceLineNo">1069</span>    }<a name="line.1069"></a>
-<span class="sourceLineNo">1070</span><a name="line.1070"></a>
-<span class="sourceLineNo">1071</span>    protected void regionMoved(int region, int oldServer, int newServer) {<a name="line.1071"></a>
-<span class="sourceLineNo">1072</span>    }<a name="line.1072"></a>
-<span class="sourceLineNo">1073</span><a name="line.1073"></a>
-<span class="sourceLineNo">1074</span>    protected abstract double cost();<a name="line.1074"></a>
+<span class="sourceLineNo">1025</span>    protected Cluster cluster;<a name="line.1025"></a>
+<span class="sourceLineNo">1026</span><a name="line.1026"></a>
+<span class="sourceLineNo">1027</span>    public CostFunction(Configuration c) {<a name="line.1027"></a>
+<span class="sourceLineNo">1028</span>    }<a name="line.1028"></a>
+<span class="sourceLineNo">1029</span><a name="line.1029"></a>
+<span class="sourceLineNo">1030</span>    boolean isNeeded() {<a name="line.1030"></a>
+<span class="sourceLineNo">1031</span>      return true;<a name="line.1031"></a>
+<span class="sourceLineNo">1032</span>    }<a name="line.1032"></a>
+<span class="sourceLineNo">1033</span>    float getMultiplier() {<a name="line.1033"></a>
+<span class="sourceLineNo">1034</span>      return multiplier;<a name="line.1034"></a>
+<span class="sourceLineNo">1035</span>    }<a name="line.1035"></a>
+<span class="sourceLineNo">1036</span><a name="line.1036"></a>
+<span class="sourceLineNo">1037</span>    void setMultiplier(float m) {<a name="line.1037"></a>
+<span class="sourceLineNo">1038</span>      this.multiplier = m;<a name="line.1038"></a>
+<span class="sourceLineNo">1039</span>    }<a name="line.1039"></a>
+<span class="sourceLineNo">1040</span><a name="line.1040"></a>
+<span class="sourceLineNo">1041</span>    /** Called once per LB invocation to give the cost function<a name="line.1041"></a>
+<span class="sourceLineNo">1042</span>     * to initialize it's state, and perform any costly calculation.<a name="line.1042"></a>
+<span class="sourceLineNo">1043</span>     */<a name="line.1043"></a>
+<span class="sourceLineNo">1044</span>    void init(Cluster cluster) {<a name="line.1044"></a>
+<span class="sourceLineNo">1045</span>      this.cluster = cluster;<a name="line.1045"></a>
+<span class="sourceLineNo">1046</span>    }<a name="line.1046"></a>
+<span class="sourceLineNo">1047</span><a name="line.1047"></a>
+<span class="sourceLineNo">1048</span>    /** Called once per cluster Action to give the cost function<a name="line.1048"></a>
+<span class="sourceLineNo">1049</span>     * an opportunity to update it's state. postAction() is always<a name="line.1049"></a>
+<span class="sourceLineNo">1050</span>     * called at least once before cost() is called with the cluster<a name="line.1050"></a>
+<span class="sourceLineNo">1051</span>     * that this action is performed on. */<a name="line.1051"></a>
+<span class="sourceLineNo">1052</span>    void postAction(Action action) {<a name="line.1052"></a>
+<span class="sourceLineNo">1053</span>      switch (action.type) {<a name="line.1053"></a>
+<span class="sourceLineNo">1054</span>      case NULL: break;<a name="line.1054"></a>
+<span class="sourceLineNo">1055</span>      case ASSIGN_REGION:<a name="line.1055"></a>
+<span class="sourceLineNo">1056</span>        AssignRegionAction ar = (AssignRegionAction) action;<a name="line.1056"></a>
+<span class="sourceLineNo">1057</span>        regionMoved(ar.region, -1, ar.server);<a name="line.1057"></a>
+<span class="sourceLineNo">1058</span>        break;<a name="line.1058"></a>
+<span class="sourceLineNo">1059</span>      case MOVE_REGION:<a name="line.1059"></a>
+<span class="sourceLineNo">1060</span>        MoveRegionAction mra = (MoveRegionAction) action;<a name="line.1060"></a>
+<span class="sourceLineNo">1061</span>        regionMoved(mra.region, mra.fromServer, mra.toServer);<a name="line.1061"></a>
+<span class="sourceLineNo">1062</span>        break;<a name="line.1062"></a>
+<span class="sourceLineNo">1063</span>      case SWAP_REGIONS:<a name="line.1063"></a>
+<span class="sourceLineNo">1064</span>        SwapRegionsAction a = (SwapRegionsAction) action;<a name="line.1064"></a>
+<span class="sourceLineNo">1065</span>        regionMoved(a.fromRegion, a.fromServer, a.toServer);<a name="line.1065"></a>
+<span class="sourceLineNo">1066</span>        regionMoved(a.toRegion, a.toServer, a.fromServer);<a name="line.1066"></a>
+<span class="sourceLineNo">1067</span>        break;<a name="line.1067"></a>
+<span class="sourceLineNo">1068</span>      default:<a name="line.1068"></a>
+<span class="sourceLineNo">1069</span>        throw new RuntimeException("Uknown action:" + action.type);<a name="line.1069"></a>
+<span class="sourceLineNo">1070</span>      }<a name="line.1070"></a>
+<span class="sourceLineNo">1071</span>    }<a name="line.1071"></a>
+<span class="sourceLineNo">1072</span><a name="line.1072"></a>
+<span class="sourceLineNo">1073</span>    protected void regionMoved(int region, int oldServer, int newServer) {<a name="line.1073"></a>
+<span class="sourceLineNo">1074</span>    }<a name="line.1074"></a>
 <span class="sourceLineNo">1075</span><a name="line.1075"></a>
-<span class="sourceLineNo">1076</span>    @SuppressWarnings("checkstyle:linelength")<a name="line.1076"></a>
-<span class="sourceLineNo">1077</span>    /**<a name="line.1077"></a>
-<span class="sourceLineNo">1078</span>     * Function to compute a scaled cost using<a name="line.1078"></a>
-<span class="sourceLineNo">1079</span>     * {@link org.apache.commons.math3.stat.descriptive.DescriptiveStatistics#DescriptiveStatistics()}.<a name="line.1079"></a>
-<span class="sourceLineNo">1080</span>     * It assumes that this is a zero sum set of costs.  It assumes that the worst case<a name="line.1080"></a>
-<span class="sourceLineNo">1081</span>     * possible is all of the elements in one region server and the rest having 0.<a name="line.1081"></a>
-<span class="sourceLineNo">1082</span>     *<a name="line.1082"></a>
-<span class="sourceLineNo">1083</span>     * @param stats the costs<a name="line.1083"></a>
-<span class="sourceLineNo">1084</span>     * @return a scaled set of costs.<a name="line.1084"></a>
-<span class="sourceLineNo">1085</span>     */<a name="line.1085"></a>
-<span class="sourceLineNo">1086</span>    protected double costFromArray(double[] stats) {<a name="line.1086"></a>
-<span class="sourceLineNo">1087</span>      double totalCost = 0;<a name="line.1087"></a>
-<span class="sourceLineNo">1088</span>      double total = getSum(stats);<a name="line.1088"></a>
-<span class="sourceLineNo">1089</span><a name="line.1089"></a>
-<span class="sourceLineNo">1090</span>      double count = stats.length;<a name="line.1090"></a>
-<span class="sourceLineNo">1091</span>      double mean = total/count;<a name="line.1091"></a>
-<span class="sourceLineNo">1092</span><a name="line.1092"></a>
-<span class="sourceLineNo">1093</span>      // Compute max as if all region servers had 0 and one had the sum of all costs.  This must be<a name="line.1093"></a>
-<span class="sourceLineNo">1094</span>      // a zero sum cost for this to make sense.<a name="line.1094"></a>
-<span class="sourceLineNo">1095</span>      double max = ((count - 1) * mean) + (total - mean);<a name="line.1095"></a>
-<span class="sourceLineNo">1096</span><a name="line.1096"></a>
-<span class="sourceLineNo">1097</span>      // It's possible that there aren't enough regions to go around<a name="line.1097"></a>
-<span class="sourceLineNo">1098</span>      double min;<a name="line.1098"></a>
-<span class="sourceLineNo">1099</span>      if (count &gt; total) {<a name="line.1099"></a>
-<span class="sourceLineNo">1100</span>        min = ((count - total) * mean) + ((1 - mean) * total);<a name="line.1100"></a>
-<span class="sourceLineNo">1101</span>      } else {<a name="line.1101"></a>
-<span class="sourceLineNo">1102</span>        // Some will have 1 more than everything else.<a name="line.1102"></a>
-<span class="sourceLineNo">1103</span>        int numHigh = (int) (total - (Math.floor(mean) * count));<a name="line.1103"></a>
-<span class="sourceLineNo">1104</span>        int numLow = (int) (count - numHigh);<a name="line.1104"></a>
-<span class="sourceLineNo">1105</span><a name="line.1105"></a>
-<span class="sourceLineNo">1106</span>        min = (numHigh * (Math.ceil(mean) - mean)) + (numLow * (mean - Math.floor(mean)));<a name="line.1106"></a>
+<span class="sourceLineNo">1076</span>    protected abstract double cost();<a name="line.1076"></a>
+<span class="sourceLineNo">1077</span><a name="line.1077"></a>
+<span class="sourceLineNo">1078</span>    @SuppressWarnings("checkstyle:linelength")<a name="line.1078"></a>
+<span class="sourceLineNo">1079</span>    /**<a name="line.1079"></a>
+<span class="sourceLineNo">1080</span>     * Function to compute a scaled cost using<a name="line.1080"></a>
+<span class="sourceLineNo">1081</span>     * {@link org.apache.commons.math3.stat.descriptive.DescriptiveStatistics#DescriptiveStatistics()}.<a name="line.1081"></a>
+<span class="sourceLineNo">1082</span>     * It assumes that this is a zero sum set of costs.  It assumes that the worst case<a name="line.1082"></a>
+<span class="sourceLineNo">1083</span>     * possible is all of the elements in one region server and the rest having 0.<a name="line.1083"></a>
+<span class="sourceLineNo">1084</span>     *<a name="line.1084"></a>
+<span class="sourceLineNo">1085</span>     * @param stats the costs<a name="line.1085"></a>
+<span class="sourceLineNo">1086</span>     * @return a scaled set of costs.<a name="line.1086"></a>
+<span class="sourceLineNo">1087</span>     */<a name="line.1087"></a>
+<span class="sourceLineNo">1088</span>    protected double costFromArray(double[] stats) {<a name="line.1088"></a>
+<span class="sourceLineNo">1089</span>      double totalCost = 0;<a name="line.1089"></a>
+<span class="sourceLineNo">1090</span>      double total = getSum(stats);<a name="line.1090"></a>
+<span class="sourceLineNo">1091</span><a name="line.1091"></a>
+<span class="sourceLineNo">1092</span>      double count = stats.length;<a name="line.1092"></a>
+<span class="sourceLineNo">1093</span>      double mean = total/count;<a name="line.1093"></a>
+<span class="sourceLineNo">1094</span><a name="line.1094"></a>
+<span class="sourceLineNo">1095</span>      // Compute max as if all region servers had 0 and one had the sum of all costs.  This must be<a name="line.1095"></a>
+<span class="sourceLineNo">1096</span>      // a zero sum cost for this to make sense.<a name="line.1096"></a>
+<span class="sourceLineNo">1097</span>      double max = ((count - 1) * mean) + (total - mean);<a name="line.1097"></a>
+<span class="sourceLineNo">1098</span><a name="line.1098"></a>
+<span class="sourceLineNo">1099</span>      // It's possible that there aren't enough regions to go around<a name="line.1099"></a>
+<span class="sourceLineNo">1100</span>      double min;<a name="line.1100"></a>
+<span class="sourceLineNo">1101</span>      if (count &gt; total) {<a name="line.1101"></a>
+<span class="sourceLineNo">1102</span>        min = ((count - total) * mean) + ((1 - mean) * total);<a name="line.1102"></a>
+<span class="sourceLineNo">1103</span>      } else {<a name="line.1103"></a>
+<span class="sourceLineNo">1104</span>        // Some will have 1 more than everything else.<a name="line.1104"></a>
+<span class="sourceLineNo">1105</span>        int numHigh = (int) (total - (Math.floor(mean) * count));<a name="line.1105"></a>
+<span class="sourceLineNo">1106</span>        int numLow = (int) (count - numHigh);<a name="line.1106"></a>
 <span class="sourceLineNo">1107</span><a name="line.1107"></a>
-<span class="sourceLineNo">1108</span>      }<a name="line.1108"></a>
-<span class="sourceLineNo">1109</span>      min = Math.max(0, min);<a name="line.1109"></a>
-<span class="sourceLineNo">1110</span>      for (int i=0; i&lt;stats.length; i++) {<a name="line.1110"></a>
-<span class="sourceLineNo">1111</span>        double n = stats[i];<a name="line.1111"></a>
-<span class="sourceLineNo">1112</span>        double diff = Math.abs(mean - n);<a name="line.1112"></a>
-<span class="sourceLineNo">1113</span>        totalCost += diff;<a name="line.1113"></a>
-<span class="sourceLineNo">1114</span>      }<a name="line.1114"></a>
-<span class="sourceLineNo">1115</span><a name="line.1115"></a>
-<span class="sourceLineNo">1116</span>      double scaled =  scale(min, max, totalCost);<a name="line.1116"></a>
-<span class="sourceLineNo">1117</span>      return scaled;<a name="line.1117"></a>
-<span class="sourceLineNo">1118</span>    }<a name="line.1118"></a>
-<span class="sourceLineNo">1119</span><a name="line.1119"></a>
-<span class="sourceLineNo">1120</span>    private double getSum(double[] stats) {<a name="line.1120"></a>
-<span class="sourceLineNo">1121</span>      double total = 0;<a name="line.1121"></a>
-<span class="sourceLineNo">1122</span>      for(double s:stats) {<a name="line.1122"></a>
-<span class="sourceLineNo">1123</span>        total += s;<a name="line.1123"></a>
-<span class="sourceLineNo">1124</span>      }<a name="line.1124"></a>
-<span class="sourceLineNo">1125</span>      return total;<a name="line.1125"></a>
-<span class="sourceLineNo">1126</span>    }<a name="line.1126"></a>
-<span class="sourceLineNo">1127</span><a name="line.1127"></a>
-<span class="sourceLineNo">1128</span>    /**<a name="line.1128"></a>
-<span class="sourceLineNo">1129</span>     * Scale the value between 0 and 1.<a name="line.1129"></a>
-<span class="sourceLineNo">1130</span>     *<a name="line.1130"></a>
-<span class="sourceLineNo">1131</span>     * @param min   Min value<a name="line.1131"></a>
-<span class="sourceLineNo">1132</span>     * @param max   The Max value<a name="line.1132"></a>
-<span class="sourceLineNo">1133</span>     * @param value The value to be scaled.<a name="line.1133"></a>
-<span class="sourceLineNo">1134</span>     * @return The scaled value.<a name="line.1134"></a>
-<span class="sourceLineNo">1135</span>     */<a name="line.1135"></a>
-<span class="sourceLineNo">1136</span>    protected double scale(double min, double max, double value) {<a name="line.1136"></a>
-<span class="sourceLineNo">1137</span>      if (max &lt;= min || value &lt;= min) {<a name="line.1137"></a>
-<span class="sourceLineNo">1138</span>        return 0;<a name="line.1138"></a>
-<span class="sourceLineNo">1139</span>      }<a name="line.1139"></a>
-<span class="sourceLineNo">1140</span>      if ((max - min) == 0) return 0;<a name="line.1140"></a>
-<span class="sourceLineNo">1141</span><a name="line.1141"></a>
-<span class="sourceLineNo">1142</span>      return Math.max(0d, Math.min(1d, (value - min) / (max - min)));<a name="line.1142"></a>
-<span class="sourceLineNo">1143</span>    }<a name="line.1143"></a>
-<span class="sourceLineNo">1144</span>  }<a name="line.1144"></a>
-<span class="sourceLineNo">1145</span><a name="line.1145"></a>
-<span class="sourceLineNo">1146</span>  /**<a name="line.1146"></a>
-<span class="sourceLineNo">1147</span>   * Given the starting state of the regions and a potential ending state<a name="line.1147"></a>
-<span class="sourceLineNo">1148</span>   * compute cost based upon the number of regions that have moved.<a name="line.1148"></a>
-<span class="sourceLineNo">1149</span>   */<a name="line.1149"></a>
-<span class="sourceLineNo">1150</span>  static class MoveCostFunction extends CostFunction {<a name="line.1150"></a>
-<span class="sourceLineNo">1151</span>    private static final String MOVE_COST_KEY = "hbase.master.balancer.stochastic.moveCost";<a name="line.1151"></a>
-<span class="sourceLineNo">1152</span>    private static final String MAX_MOVES_PERCENT_KEY =<a name="line.1152"></a>
-<span class="sourceLineNo">1153</span>        "hbase.master.balancer.stochastic.maxMovePercent";<a name="line.1153"></a>
-<span class="sourceLineNo">1154</span>    private static final float DEFAULT_MOVE_COST = 7;<a name="line.1154"></a>
-<span class="sourceLineNo">1155</span>    private static final int DEFAULT_MAX_MOVES = 600;<a name="line.1155"></a>
-<span class="sourceLineNo">1156</span>    private static final float DEFAULT_MAX_MOVE_PERCENT = 0.25f;<a name="line.1156"></a>
-<span class="sourceLineNo">1157</span><a name="line.1157"></a>
-<span class="sourceLineNo">1158</span>    private final float maxMovesPercent;<a name="line.1158"></a>
+<span class="sourceLineNo">1108</span>        min = (numHigh * (Math.ceil(mean) - mean)) + (numLow * (mean - Math.floor(mean)));<a name="line.1108"></a>
+<span class="sourceLineNo">1109</span><a name="line.1109"></a>
+<span class="sourceLineNo">1110</span>      }<a name="line.1110"></a>
+<span class="sourceLineNo">1111</span>      min = Math.max(0, min);<a name="line.1111"></a>
+<span class="sourceLineNo">1112</span>      for (int i=0; i&lt;stats.length; i++) {<a name="line.1112"></a>
+<span class="sourceLineNo">1113</span>        double n = stats[i];<a name="line.1113"></a>
+<span class="sourceLineNo">1114</span>        double diff = Math.abs(mean - n);<a name="line.1114"></a>
+<span class="sourceLineNo">1115</span>        totalCost += diff;<a name="line.1115"></a>
+<span class="sourceLineNo">1116</span>      }<a name="line.1116"></a>
+<span class="sourceLineNo">1117</span><a name="line.1117"></a>
+<span class="sourceLineNo">1118</span>      double scaled =  scale(min, max, totalCost);<a name="line.1118"></a>
+<span class="sourceLineNo">1119</span>      return scaled;<a name="line.1119"></a>
+<span class="sourceLineNo">1120</span>    }<a name="line.1120"></a>
+<span class="sourceLineNo">1121</span><a name="line.1121"></a>
+<span class="sourceLineNo">1122</span>    private double getSum(double[] stats) {<a name="line.1122"></a>
+<span class="sourceLineNo">1123</span>      double total = 0;<a name="line.1123"></a>
+<span class="sourceLineNo">1124</span>      for(double s:stats) {<a name="line.1124"></a>
+<span class="sourceLineNo">1125</span>        total += s;<a name="line.1125"></a>
+<span class="sourceLineNo">1126</span>      }<a name="line.1126"></a>
+<span class="sourceLineNo">1127</span>      return total;<a name="line.1127"></a>
+<span class="sourceLineNo">1128</span>    }<a name="line.1128"></a>
+<span class="sourceLineNo">1129</span><a name="line.1129"></a>
+<span class="sourceLineNo">1130</span>    /**<a name="line.1130"></a>
+<span class="sourceLineNo">1131</span>     * Scale the value between 0 and 1.<a name="line.1131"></a>
+<span class="sourceLineNo">1132</span>     *<a name="line.1132"></a>
+<span class="sourceLineNo">1133</span>     * @param min   Min value<a name="line.1133"></a>
+<span class="sourceLineNo">1134</span>     * @param max   The Max value<a name="line.1134"></a>
+<span class="sourceLineNo">1135</span>     * @param value The value to be scaled.<a name="line.1135"></a>
+<span class="sourceLineNo">1136</span>     * @return The scaled value.<a name="line.1136"></a>
+<span class="sourceLineNo">1137</span>     */<a name="line.1137"></a>
+<span class="sourceLineNo">1138</span>    protected double scale(double min, double max, double value) {<a name="line.1138"></a>
+<span class="sourceLineNo">1139</span>      if (max &lt;= min || value &lt;= min) {<a name="line.1139"></a>
+<span class="sourceLineNo">1140</span>        return 0;<a name="line.1140"></a>
+<span class="sourceLineNo">1141</span>      }<a name="line.1141"></a>
+<span class="sourceLineNo">1142</span>      if ((max - min) == 0) return 0;<a name="line.1142"></a>
+<span class="sourceLineNo">1143</span><a name="line.1143"></a>
+<span class="sourceLineNo">1144</span>      return Math.max(0d, Math.min(1d, (value - min) / (max - min)));<a name="line.1144"></a>
+<span class="sourceLineNo">1145</span>    }<a name="line.1145"></a>
+<span class="sourceLineNo">1146</span>  }<a name="line.1146"></a>
+<span class="sourceLineNo">1147</span><a name="line.1147"></a>
+<span class="sourceLineNo">1148</span>  /**<a name="line.1148"></a>
+<span class="sourceLineNo">1149</span>   * Given the starting state of the regions and a potential ending state<a name="line.1149"></a>
+<span class="sourceLineNo">1150</span>   * compute cost based upon the number of regions that have moved.<a name="line.1150"></a>
+<span class="sourceLineNo">1151</span>   */<a name="line.1151"></a>
+<span class="sourceLineNo">1152</span>  static class MoveCostFunction extends CostFunction {<a name="line.1152"></a>
+<span class="sourceLineNo">1153</span>    private static final String MOVE_COST_KEY = "hbase.master.balancer.stochastic.moveCost";<a name="line.1153"></a>
+<span class="sourceLineNo">1154</span>    private static final String MAX_MOVES_PERCENT_KEY =<a name="line.1154"></a>
+<span class="sourceLineNo">1155</span>        "hbase.master.balancer.stochastic.maxMovePercent";<a name="line.1155"></a>
+<span class="sourceLineNo">1156</span>    private static final float DEFAULT_MOVE_COST = 7;<a name="line.1156"></a>
+<span class="sourceLineNo">1157</span>    private static final int DEFAULT_MAX_MOVES = 600;<a name="line.1157"></a>
+<span class="sourceLineNo">1158</span>    private static final float DEFAULT_MAX_MOVE_PERCENT = 0.25f;<a name="line.1158"></a>
 <span class="sourceLineNo">1159</span><a name="line.1159"></a>
-<span class="sourceLineNo">1160</span>    MoveCostFunction(Configuration conf) {<a name="line.1160"></a>
-<span class="sourceLineNo">1161</span>      super(conf);<a name="line.1161"></a>
-<span class="sourceLineNo">1162</span><a name="line.1162"></a>
-<span class="sourceLineNo">1163</span>      // Move cost multiplier should be the same cost or higher than the rest of the costs to ensure<a name="line.1163"></a>
-<span class="sourceLineNo">1164</span>      // that large benefits are need to overcome the cost of a move.<a name="line.1164"></a>
-<span class="sourceLineNo">1165</span>      this.setMultiplier(conf.getFloat(MOVE_COST_KEY, DEFAULT_MOVE_COST));<a name="line.1165"></a>
-<span class="sourceLineNo">1166</span>      // What percent of the number of regions a single run of the balancer can move.<a name="line.1166"></a>
-<span class="sourceLineNo">1167</span>      maxMovesPercent = conf.getFloat(MAX_MOVES_PERCENT_KEY, DEFAULT_MAX_MOVE_PERCENT);<a name="line.1167"></a>
-<span class="sourceLineNo">1168</span>    }<a name="line.1168"></a>
-<span class="sourceLineNo">1169</span><a name="line.1169"></a>
-<span class="sourceLineNo">1170</span>    @Override<a name="line.1170"></a>
-<span class="sourceLineNo">1171</span>    protected double cost() {<a name="line.1171"></a>
-<span class="sourceLineNo">1172</span>      // Try and size the max number of Moves, but always be prepared to move some.<a name="line.1172"></a>
-<span class="sourceLineNo">1173</span>      int maxMoves = Math.max((int) (cluster.numRegions * maxMovesPercent),<a name="line.1173"></a>
-<span class="sourceLineNo">1174</span>          DEFAULT_MAX_MOVES);<a name="line.1174"></a>
-<span class="sourceLineNo">1175</span><a name="line.1175"></a>
-<span class="sourceLineNo">1176</span>      double moveCost = cluster.numMovedRegions;<a name="line.1176"></a>
+<span class="sourceLineNo">1160</span>    private final float maxMovesPercent;<a name="line.1160"></a>
+<span class="sourceLineNo">1161</span><a name="line.1161"></a>
+<span class="sourceLineNo">1162</span>    MoveCostFunction(Configuration conf) {<a name="line.1162"></a>
+<span class="sourceLineNo">1163</span>      super(conf);<a name="line.1163"></a>
+<span class="sourceLineNo">1164</span><a name="line.1164"></a>
+<span class="sourceLineNo">1165</span>      // Move cost multiplier should be the same cost or higher than the rest of the costs to ensure<a name="line.1165"></a>
+<span class="sourceLineNo">1166</span>      // that large benefits are need to overcome the cost of a move.<a name="line.1166"></a>
+<span class="sourceLineNo">1167</span>      this.setMultiplier(conf.getFloat(MOVE_COST_KEY, DEFAULT_MOVE_COST));<a name="line.1167"></a>
+<span class="sourceLineNo">1168</span>      // What percent of the number of regions a single run of the balancer can move.<a name="line.1168"></a>
+<span class="sourceLineNo">1169</span>      maxMovesPercent = conf.getFloat(MAX_MOVES_PERCENT_KEY, DEFAULT_MAX_MOVE_PERCENT);<a name="line.1169"></a>
+<span class="sourceLineNo">1170</span>    }<a name="line.1170"></a>
+<span class="sourceLineNo">1171</span><a name="line.1171"></a>
+<span class="sourceLineNo">1172</span>    @Override<a name="line.1172"></a>
+<span class="sourceLineNo">1173</span>    protected double cost() {<a name="line.1173"></a>
+<span class="sourceLineNo">1174</span>      // Try and size the max number of Moves, but always be prepared to move some.<a name="line.1174"></a>
+<span class="sourceLineNo">1175</span>      int maxMoves = Math.max((int) (cluster.numRegions * maxMovesPercent),<a name="line.1175"></a>
+<span class="sourceLineNo">1176</span>          DEFAULT_MAX_MOVES);<a name="line.1176"></a>
 <span class="sourceLineNo">1177</span><a name="line.1177"></a>
-<span class="sourceLineNo">1178</span>      // Don't let this single balance move more than the max moves.<a name="line.1178"></a>
-<span class="sourceLineNo">1179</span>      // This allows better scaling to accurately represent the actual cost of a move.<a name="line.1179"></a>
-<span class="sourceLineNo">1180</span>      if (moveCost &gt; maxMoves) {<a name="line.1180"></a>
-<span class="sourceLineNo">1181</span>        return 1000000;   // return a number much greater than any of the other cost<a name="line.1181"></a>
-<span class="sourceLineNo">1182</span>      }<a name="line.1182"></a>
-<span class="sourceLineNo">1183</span><a name="line.1183"></a>
-<span class="sourceLineNo">1184</span>      return scale(0, Math.min(cluster.numRegions, maxMoves), moveCost);<a name="line.1184"></a>
-<span class="sourceLineNo">1185</span>    }<a name="line.1185"></a>
-<span class="sourceLineNo">1186</span>  }<a name="line.1186"></a>
-<span class="sourceLineNo">1187</span><a name="line.1187"></a>
-<span class="sourceLineNo">1188</span>  /**<a name="line.1188"></a>
-<span class="sourceLineNo">1189</span>   * Compute the cost of a potential cluster state from skew in number of<a name="line.1189"></a>
-<span class="sourceLineNo">1190</span>   * regions on a cluster.<a name="line.1190"></a>
-<span class="sourceLineNo">1191</span>   */<a name="line.1191"></a>
-<span class="sourceLineNo">1192</span>  static class RegionCountSkewCostFunction extends CostFunction {<a name="line.1192"></a>
-<span class="sourceLineNo">1193</span>    private static final String REGION_COUNT_SKEW_COST_KEY =<a name="line.1193"></a>
-<span class="sourceLineNo">1194</span>        "hbase.master.balancer.stochastic.regionCountCost";<a name="line.1194"></a>
-<span class="sourceLineNo">1195</span>    private static final float DEFAULT_REGION_COUNT_SKEW_COST = 500;<a name="line.1195"></a>
-<span class="sourceLineNo">1196</span><a name="line.1196"></a>
-<span class="sourceLineNo">1197</span>    private double[] stats = null;<a name="line.1197"></a>
+<span class="sourceLineNo">1178</span>      double moveCost = cluster.numMovedRegions;<a name="line.1178"></a>
+<span class="sourceLineNo">1179</span><a name="line.1179"></a>
+<span class="sourceLineNo">1180</span>      // Don't let this single balance move more than the max moves.<a name="line.1180"></a>
+<span class="sourceLineNo">1181</span>      // This allows better scaling to accurately represent the actual cost of a move.<a name="line.1181"></a>
+<span class="sourceLineNo">1182</span>      if (moveCost &gt; maxMoves) {<a name="line.1182"></a>
+<span class="sourceLineNo">1183</span>        return 1000000;   // return a number much greater than any of the other cost<a name="line.1183"></a>
+<span class="sourceLineNo">1184</span>      }<a name="line.1184"></a>
+<span class="sourceLineNo">1185</span><a name="line.1185"></a>
+<span class="sourceLineNo">1186</span>      return scale(0, Math.min(cluster.numRegions, maxMoves), moveCost);<a name="line.1186"></a>
+<span class="sourceLineNo">1187</span>    }<a name="line.1187"></a>
+<span class="sourceLineNo">1188</span>  }<a name="line.1188"></a>
+<span class="sourceLineNo">1189</span><a name="line.1189"></a>
+<span class="sourceLineNo">1190</span>  /**<a name="line.1190"></a>
+<span class="sourceLineNo">1191</span>   * Compute the cost of a potential cluster state from skew in number of<a name="line.1191"></a>
+<span class="sourceLineNo">1192</span>   * regions on a cluster.<a name="line.1192"></a>
+<span class="sourceLineNo">1193</span>   */<a name="line.1193"></a>
+<span class="sourceLineNo">1194</span>  static class RegionCountSkewCostFunction extends CostFunction {<a name="line.1194"></a>
+<span class="sourceLineNo">1195</span>    private static final String REGION_COUNT_SKEW_COST_KEY =<a name="line.1195"></a>
+<span class="sourceLineNo">1196</span>        "hbase.master.balancer.stochastic.regionCountCost";<a name="line.1196"></a>
+<span class="sourceLineNo">1197</span>    private static final float DEFAULT_REGION_COUNT_SKEW_COST = 500;<a name="line.1197"></a>
 <span class="sourceLineNo">1198</span><a name="line.1198"></a>
-<span class="sourceLineNo">1199</span>    RegionCountSkewCostFunction(Configuration conf) {<a name="line.1199"></a>
-<span class="sourceLineNo">1200</span>      super(conf);<a name="line.1200"></a>
-<span class="sourceLineNo">1201</span>      // Load multiplier should be the greatest as it is the most general way to balance data.<a name="line.1201"></a>
-<span class="sourceLineNo">1202</span>      this.setMultiplier(conf.getFloat(REGION_COUNT_SKEW_COST_KEY, DEFAULT_REGION_COUNT_SKEW_COST));<a name="line.1202"></a>
-<span class="sourceLineNo">1203</span>    }<a name="line.1203"></a>
-<span class="sourceLineNo">1204</span><a name="line.1204"></a>
-<span class="sourceLineNo">1205</span>    @Override<a name="line.1205"></a>
-<span class="sourceLineNo">1206</span>    protected double cost() {<a name="line.1206"></a>
-<span class="sourceLineNo">1207</span>      if (stats == null || stats.length != cluster.numServers) {<a name="line.1207"></a>
-<span class="sourceLineNo">1208</span>        stats = new double[cluster.numServers];<a name="line.1208"></a>
-<span class="sourceLineNo">1209</span>      }<a name="line.1209"></a>
-<span class="sourceLineNo">1210</span><a name="line.1210"></a>
-<span class="sourceLineNo">1211</span>      for (int i =0; i &lt; cluster.numServers; i++) {<a name="line.1211"></a>
-<span class="sourceLineNo">1212</span>        stats[i] = cluster.regionsPerServer[i].length;<a name="line.1212"></a>
-<span class="sourceLineNo">1213</span>      }<a name="line.1213"></a>
-<span class="sourceLineNo">1214</span><a name="line.1214"></a>
-<span class="sourceLineNo">1215</span>      return costFromArray(stats);<a name="line.1215"></a>
-<span class="sourceLineNo">1216</span>    }<a name="line.1216"></a>
-<span class="sourceLineNo">1217</span>  }<a name="line.1217"></a>
-<span class="sourceLineNo">1218</span><a name="line.1218"></a>
-<span class="sourceLineNo">1219</span>  /**<a name="line.1219"></a>
-<span class="sourceLineNo">1220</span>   * Compute the cost of a potential cluster state from skew in number of<a name="line.1220"></a>
-<span class="sourceLineNo">1221</span>   * primary regions on a cluster.<a name="line.1221"></a>
-<span class="sourceLineNo">1222</span>   */<a name="line.1222"></a>
-<span class="sourceLineNo">1223</span>  static class PrimaryRegionCountSkewCostFunction extends CostFunction {<a name="line.1223"></a>
-<span class="sourceLineNo">1224</span>    private static final String PRIMARY_REGION_COUNT_SKEW_COST_KEY =<a name="line.1224"></a>
-<span class="sourceLineNo">1225</span>        "hbase.master.balancer.stochastic.primaryRegionCountCost";<a name="line.1225"></a>
-<span class="sourceLineNo">1226</span>    private static final float DEFAULT_PRIMARY_REGION_COUNT_SKEW_COST = 500;<a name="line.1226"></a>
-<span class="sourceLineNo">1227</span><a name="line.1227"></a>
-<span class="sourceLineNo">1228</span>    private double[] stats = null;<a name="line.1228"></a>
+<span class="sourceLineNo">1199</span>    private double[] stats = null;<a name="line.1199"></a>
+<span class="sourceLineNo">1200</span><a name="line.1200"></a>
+<span class="sourceLineNo">1201</span>    RegionCountSkewCostFunction(Configuration conf) {<a name="line.1201"></a>
+<span class="sourceLineNo">1202</span>      super(conf);<a name="line.1202"></a>
+<span class="sourceLineNo">1203</span>      // Load multiplier should be the greatest as it is the most general way to balance data.<a name="line.1203"></a>
+<span class="sourceLineNo">1204</span>      this.setMultiplier(conf.getFloat(REGION_COUNT_SKEW_COST_KEY, DEFAULT_REGION_COUNT_SKEW_COST));<a name="line.1204"></a>
+<span class="sourceLineNo">1205</span>    }<a name="line.1205"></a>
+<span class="sourceLineNo">1206</span><a name="line.1206"></a>
+<span class="sourceLineNo">1207</span>    @Override<a name="line.1207"></a>
+<span class="sourceLineNo">1208</span>    protected double cost() {<a name="line.1208"></a>
+<span class="sourceLineNo">1209</span>      if (stats == null || stats.length != cluster.numServers) {<a name="line.1209"></a>
+<span class="sourceLineNo">1210</span>        stats = new double[cluster.numServers];<a name="line.1210"></a>
+<span class="sourceLineNo">1211</span>      }<a name="line.1211"></a>
+<span class="sourceLineNo">1212</span><a name="line.1212"></a>
+<span class="sourceLineNo">1213</span>      for (int i =0; i &lt; cluster.numServers; i++) {<a name="line.1213"></a>
+<span class="sourceLineNo">1214</span>        stats[i] = cluster.regionsPerServer[i].length;<a name="line.1214"></a>
+<span class="sourceLineNo">1215</span>      }<a name="line.1215"></a>
+<span class="sourceLineNo">1216</span><a name="line.1216"></a>
+<span class="sourceLineNo">1217</span>      return costFromArray(stats);<a name="line.1217"></a>
+<span class="sourceLineNo">1218</span>    }<a name="line.1218"></a>
+<span class="sourceLineNo">1219</span>  }<a name="line.1219"></a>
+<span class="sourceLineNo">1220</span><a name="line.1220"></a>
+<span class="sourceLineNo">1221</span>  /**<a name="line.1221"></a>
+<span class="sourceLineNo">1222</span>   * Compute the cost of a potential cluster state from skew in number of<a name="line.1222"></a>
+<span class="sourceLineNo">1223</span>   * primary regions on a cluster.<a name="line.1223"></a>
+<span class="sourceLineNo">1224</span>   */<a name="line.1224"></a>
+<span class="sourceLineNo">1225</span>  static class PrimaryRegionCountSkewCostFunction extends CostFunction {<a name="line.1225"></a>
+<span class="sourceLineNo">1226</span>    private static final String PRIMARY_REGION_COUNT_SKEW_COST_KEY =<a name="line.1226"></a>
+<span class="sourceLineNo">1227</span>        "hbase.master.balancer.stochastic.primaryRegionCountCost";<a name="line.1227"></a>
+<span class="sourceLineNo">1228</span>    private static final float DEFAULT_PRIMARY_REGION_COUNT_SKEW_COST = 500;<a name="line.1228"></a>
 <span class="sourceLineNo">1229</span><a name="line.1229"></a>
-<span class="sourceLineNo">1230</span>    PrimaryRegionCountSkewCostFunction(Configuration conf) {<a name="line.1230"></a>
-<span class="sourceLineNo">1231</span>      super(conf);<a name="line.1231"></a>
-<span class="sourceLineNo">1232</span>      // Load multiplier should be the greatest as primary regions serve majority of reads/writes.<a name="line.1232"></a>
-<span class="sourceLineNo">1233</span>      this.setMultiplier(conf.getFloat(PRIMARY_REGION_COUNT_SKEW_COST_KEY,<a name="line.1233"></a>
-<span class="sourceLineNo">1234</span>        DEFAULT_PRIMARY_REGION_COUNT_SKEW_COST));<a name="line.1234"></a>
-<span class="sourceLineNo">1235</span>    }<a name="line.1235"></a>
-<span class="sourceLineNo">1236</span><a name="line.1236"></a>
-<span class="sourceLineNo">1237</span>    @Override<a name="line.1237"></a>
-<span class="sourceLineNo">1238</span>    protected double cost() {<a name="line.1238"></a>
-<span class="sourceLineNo">1239</span>      if (!cluster.hasRegionReplicas) {<a name="line.1239"></a>
-<span class="sourceLineNo">1240</span>        return 0;<a name="line.1240"></a>
-<span class="sourceLineNo">1241</span>      }<a name="line.1241"></a>
-<span class="sourceLineNo">1242</span>      if (stats == null || stats.length != cluster.numServers) {<a name="line.1242"></a>
-<span class="sourceLineNo">1243</span>        stats = new double[cluster.numServers];<a name="line.1243"></a>
-<span class="sourceLineNo">1244</span>      }<a name="line.1244"></a>
-<span class="sourceLineNo">1245</span><a name="line.1245"></a>
-<span class="sourceLineNo">1246</span>      for (int i = 0; i &lt; cluster.numServers; i++) {<a name="line.1246"></a>
-<span class="sourceLineNo">1247</span>        stats[i] = 0;<a name="line.1247"></a>
-<span class="sourceLineNo">1248</span>        for (int regionIdx : cluster.regionsPerServer[i]) {<a name="line.1248"></a>
-<span class="sourceLineNo">1249</span>          if (regionIdx == cluster.regionIndexToPrimaryIndex[regionIdx]) {<a name="line.1249"></a>
-<span class="sourceLineNo">1250</span>            stats[i]++;<a name="line.1250"></a>
-<span class="sourceLineNo">1251</span>          }<a name="line.1251"></a>
-<span class="sourceLineNo">1252</span>        }<a name="line.1252"></a>
-<span class="sourceLineNo">1253</span>      }<a name="line.1253"></a>
-<span class="sourceLineNo">1254</span><a name="line.1254"></a>
-<span class="sourceLineNo">1255</span>      return costFromArray(stats);<a name="line.1255"></a>
-<span class="sourceLineNo">1256</span>    }<a name="line.1256"></a>
-<span class="sourceLineNo">1257</span>  }<a name="line.1257"></a>
-<span class="sourceLineNo">1258</span><a name="line.1258"></a>
-<span class="sourceLineNo">1259</span>  /**<a name="line.1259"></a>
-<span class="sourceLineNo">1260</span>   * Compute the cost of a potential cluster configuration based upon how evenly<a name="line.1260"></a>
-<span class="sourceLineNo">1261</span>   * distributed tables are.<a name="line.1261"></a>
-<span class="sourceLineNo">1262</span>   */<a name="line.1262"></a>
-<span class="sourceLineNo">1263</span>  static class TableSkewCostFunction extends CostFunction {<a name="line.1263"></a>
-<span class="sourceLineNo">1264</span><a name="line.1264"></a>
-<span class="sourceLineNo">1265</span>    private static final String TABLE_SKEW_COST_KEY =<a name="line.1265"></a>
-<span class="sourceLineNo">1266</span>        "hbase.master.balancer.stochastic.tableSkewCost";<a name="line.1266"></a>
-<span class="sourceLineNo">1267</span>    private static final float DEFAULT_TABLE_SKEW_COST = 35;<a name="line.1267"></a>
-<span class="sourceLineNo">1268</span><a name="line.1268"></a>
-<span class="sourceLineNo">1269</span>    TableSkewCostFunction(Configuration conf) {<a name="line.1269"></a>
-<span class="sourceLineNo">1270</span>      super(conf);<a name="line.1270"></a>
-<span class="sourceLineNo">1271</span>      this.setMultiplier(conf.getFloat(TABLE_SKEW_COST_KEY, DEFAULT_TABLE_SKEW_COST));<a name="line.1271"></a>
-<span class="sourceLineNo">1272</span>    }<a name="line.1272"></a>
-<span class="sourceLineNo">1273</span><a name="line.1273"></a>
-<span class="sourceLineNo">1274</span>    @Override<a name="line.1274"></a>
-<span class="sourceLineNo">1275</span>    protected double cost() {<a name="line.1275"></a>
-<span class="sourceLineNo">1276</span>      double max = cluster.numRegions;<a name="line.1276"></a>
-<span class="sourceLineNo">1277</span>      double min = ((double) cluster.numRegions) / cluster.numServers;<a name="line.1277"></a>
-<span class="sourceLineNo">1278</span>      double value = 0;<a name="line.1278"></a>
-<span class="sourceLineNo">1279</span><a name="line.1279"></a>
-<span class="sourceLineNo">1280</span>      for (int i = 0; i &lt; cluster.numMaxRegionsPerTable.length; i++) {<a name="line.1280"></a>
-<span class="sourceLineNo">1281</span>        value += cluster.numMaxRegionsPerTable[i];<a name="line.1281"></a>
-<span class="sourceLineNo">1282</span>      }<a name="line.1282"></a>
-<span class="sourceLineNo">1283</span><a name="line.1283"></a>
-<span class="sourceLineNo">1284</span>      return scale(min, max, value);<a name="line.1284"></a>
-<span class="sourceLineNo">1285</span>    }<a name="line.1285"></a>
-<span class="sourceLineNo">1286</span>  }<a name="line.1286"></a>
-<span class="sourceLineNo">1287</span><a name="line.1287"></a>
-<span class="sourceLineNo">1288</span>  /**<a name="line.1288"></a>
-<span class="sourceLineNo">1289</span>   * Compute a cost of a potential cluster configuration based upon where<a name="line.1289"></a>
-<span class="sourceLineNo">1290</span>   * {@link org.apache.hadoop.hbase.regionserver.HStoreFile}s are located.<a name="line.1290"></a>
-<span class="sourceLineNo">1291</span>   */<a name="line.1291"></a>
-<span class="sourceLineNo">1292</span>  static abstract class LocalityBasedCostFunction extends CostFunction {<a name="line.1292"></a>
-<span class="sourceLineNo">1293</span><a name="line.1293"></a>
-<span class="sourceLineNo">1294</span>    private final LocalityType type;<a name="line.1294"></a>
+<span class="sourceLineNo">1230</span>    private double[] stats = null;<a name="line.1230"></a>
+<span class="sourceLineNo">1231</span><a name="line.1231"></a>
+<span class="sourceLineNo">1232</span>    PrimaryRegionCountSkewCostFunction(Configuration conf) {<a name="line.1232"></a>
+<span class="sourceLineNo">1233</span>      super(conf);<a name="line.1233"></a>
+<span class="sourceLineNo">1234</span>      // Load multiplier should be the greatest as primary regions serve majority of reads/writes.<a name="line.1234"></a>
+<span class="sourceLineNo">1235</span>      this.setMultiplier(conf.getFloat(PRIMARY_REGION_COUNT_SKEW_COST_KEY,<a name="line.1235"></a>
+<span class="sourceLineNo">1236</span>        DEFAULT_PRIMARY_REGION_COUNT_SKEW_COST));<a name="line.1236"></a>
+<span class="sourceLineNo">1237</span>    }<a name="line.1237"></a>
+<span class="sourceLineNo">1238</span><a name="line.1238"></a>
+<span class="sourceLineNo">1239</span>    @Override<a name="line.1239"></a>
+<span class="sourceLineNo">1240</span>    protected double cost() {<a name="line.1240"></a>
+<span class="sourceLineNo">1241</span>      if (!cluster.hasRegionReplicas) {<a name="line.1241"></a>
+<span class="sourceLineNo">1242</span>        return 0;<a name="line.1242"></a>
+<span class="sourceLineNo">1243</span>      }<a name="line.1243"></a>
+<span class="sourceLineNo">1244</span>      if (stats == null || stats.length != cluster.numServers) {<a name="line.1244"></a>
+<span class="sourceLineNo">1245</span>        stats = new double[cluster.numServers];<a name="line.1245"></a>
+<span class="sourceLineNo">1246</span>      }<a name="line.1246"></a>
+<span class="sourceLineNo">1247</span><a name="line.1247"></a>
+<span class="sourceLineNo">1248</span>      for (int i = 0; i &lt; cluster.numServers; i++) {<a name="line.1248"></a>
+<span class="sourceLineNo">1249</span>        stats[i] = 0;<a name="line.1249"></a>
+<span class="sourceLineNo">1250</span>        for (int regionIdx : cluster.regionsPerServer[i]) {<a name="line.1250"></a>
+<span class="sourceLineNo">1251</span>          if (regionIdx == cluster.regionIndexToPrimaryIndex[regionIdx]) {<a name="line.1251"></a>
+<span class="sourceLineNo">1252</span>            stats[i]++;<a name="line.1252"></a>
+<span class="sourceLineNo">1253</span>          }<a name="line.1253"></a>
+<span class="sourceLineNo">1254</span>        }<a name="line.1254"></a>
+<span class="sourceLineNo">1255</span>      }<a name="line.1255"></a>
+<span class="sourceLineNo">1256</span><a name="line.1256"></a>
+<span class="sourceLineNo">1257</span>      return costFromArray(stats);<a name="line.1257"></a>
+<span class="sourceLineNo">1258</span>    }<a name="line.1258"></a>
+<span class="sourceLineNo">1259</span>  }<a name="line.1259"></a>
+<span class="sourceLineNo">1260</span><a name="line.1260"></a>
+<span class="sourceLineNo">1261</span>  /**<a name="line.1261"></a>
+<span class="sourceLineNo">1262</span>   * Compute the cost of a potential cluster configuration based upon how evenly<a name="line.1262"></a>
+<span class="sourceLineNo">1263</span>   * distributed tables are.<a name="line.1263"></a>
+<span class="sourceLineNo">1264</span>   */<a name="line.1264"></a>
+<span class="sourceLineNo">1265</span>  static class TableSkewCostFunction extends CostFunction {<a name="line.1265"></a>
+<span class="sourceLineNo">1266</span><a name="line.1266"></a>
+<span class="sourceLineNo">1267</span>    private static final String TABLE_SKEW_COST_KEY =<a name="line.1267"></a>
+<span class="sourceLineNo">1268</span>        "hbase.master.balancer.stochastic.tableSkewCost";<a name="line.1268"></a>
+<span class="sourceLineNo">1269</span>    private static final float DEFAULT_TABLE_SKEW_COST = 35;<a name="line.1269"></a>
+<span class="sourceLineNo">1270</span><a name="line.1270"></a>
+<span class="sourceLineNo">1271</span>    TableSkewCostFunction(Configuration conf) {<a name="line.1271"></a>
+<span class="sourceLineNo">1272</span>      super(conf);<a name="line.1272"></a>
+<span class="sourceLineNo">1273</span>      this.setMultiplier(conf.getFloat(TABLE_SKEW_COST_KEY, DEFAULT_TABLE_SKEW_COST));<a name="line.1273"></a>
+<span class="sourceLineNo">1274</span>    }<a name="line.1274"></a>
+<span class="sourceLineNo">1275</span><a name="line.1275"></a>
+<span class="sourceLineNo">1276</span>    @Override<a name="line.1276"></a>
+<span class="sourceLineNo">1277</span>    protected double cost() {<a name="line.1277"></a>
+<span class="sourceLineNo">1278</span>      double max = cluster.numRegions;<a name="line.1278"></a>
+<span class="sourceLineNo">1279</span>      double min = ((double) cluster.numRegions) / cluster.numServers;<a name="line.1279"></a>
+<span class="sourceLineNo">1280</span>      double value = 0;<a name="line.1280"></a>
+<span class="sourceLineNo">1281</span><a name="line.1281"></a>
+<span class="sourceLineNo">1282</span>      for (int i = 0; i &lt; cluster.numMaxRegionsPerTable.length; i++) {<a name="line.1282"></a>
+<span class="sourceLineNo">1283</span>        value += cluster.numMaxRegionsPerTable[i];<a name="line.1283"></a>
+<span class="sourceLineNo">1284</span>      }<a name="line.1284"></a>
+<span class="sourceLineNo">1285</span><a name="line.1285"></a>
+<span class="sourceLineNo">1286</span>      return scale(min, max, value);<a name="line.1286"></a>
+<span class="sourceLineNo">1287</span>    }<a name="line.1287"></a>
+<span class="sourceLineNo">1288</span>  }<a name="line.1288"></a>
+<span class="sourceLineNo">1289</span><a name="line.1289"></a>
+<span class="sourceLineNo">1290</span>  /**<a name="line.1290"></a>
+<span class="sourceLineNo">1291</span>   * Compute a cost of a potential cluster configuration based upon where<a name="line.1291"></a>
+<span class="sourceLineNo">1292</span>   * {@link org.apache.hadoop.hbase.regionserver.HStoreFile}s are located.<a name="line.1292"></a>
+<span class="sourceLineNo">1293</span>   */<a name="line.1293"></a>
+<span class="sourceLineNo">1294</span>  static abstract class LocalityBasedCostFunction extends CostFunction {<a name="line.1294"></a>
 <span class="sourceLineNo">1295</span><a name="line.1295"></a>
-<span class="sourceLineNo">1296</span>    private double bestLocality; // best case locality across cluster weighted by local data size<a name="line.1296"></a>
-<span class="sourceLineNo">1297</span>    private double locality; // current locality across cluster weighted by local data size<a name="line.1297"></a>
-<span class="sourceLineNo">1298</span><a name="line.1298"></a>
-<span class="sourceLineNo">1299</span>    private MasterServices services;<a name="line.1299"></a>
+<span class="sourceLineNo">1296</span>    private final LocalityType type;<a name="line.1296"></a>
+<span class="sourceLineNo">1297</span><a name="line.1297"></a>
+<span class="sourceLineNo">1298</span>    private double bestLocality; // best case locality across cluster weighted by local data size<a name="line.1298"></a>
+<span class="sourceLineNo">1299</span>    private double locality; // current locality across cluster weighted by local data size<a name="line.1299"></a>
 <span class="sourceLineNo">1300</span><a name="line.1300"></a>
-<span class="sourceLineNo">1301</span>    LocalityBasedCostFunction(Configuration conf,<a name="line.1301"></a>
-<span class="sourceLineNo">1302</span>                              MasterServices srv,<a name="line.1302"></a>
-<span class="sourceLineNo">1303</span>                              LocalityType type,<a name="line.1303"></a>
-<span class="sourceLineNo">1304</span>                              String localityCostKey,<a name="line.1304"></a>
-<span class="sourceLineNo">1305</span>                              float defaultLocalityCost) {<a name="line.1305"></a>
-<span class="sourceLineNo">1306</span>      super(conf);<a name="line.1306"></a>
-<span class="sourceLineNo">1307</span>      this.type = type;<a name="line.1307"></a>
-<span class="sourceLineNo">1308</span>      this.setMultiplier(conf.getFloat(localityCostKey, defaultLocalityCost));<a name="line.1308"></a>
-<span class="sourceLineNo">1309</span>      this.services = srv;<a name="line.1309"></a>
-<span class="sourceLineNo">1310</span>      this.locality = 0.0;<a name="line.1310"></a>
-<span class="sourceLineNo">1311</span>      this.bestLocality = 0.0;<a name="line.1311"></a>
-<span class="sourceLineNo">1312</span>    }<a name="line.1312"></a>
-<span class="sourceLineNo">1313</span><a name="line.1313"></a>
-<span class="sourceLineNo">1314</span>    /**<a name="line.1314"></a>
-<span class="sourceLineNo">1315</span>     * Maps region to the current entity (server or rack) on which it is stored<a name="line.1315"></a>
-<span class="sourceLineNo">1316</span>     */<a name="line.1316"></a>
-<span class="sourceLineNo">1317</span>    abstract int regionIndexToEntityIndex(int region);<a name="line.1317"></a>
-<span class="sourceLineNo">1318</span><a name="line.1318"></a>
-<span class="sourceLineNo">1319</span>    public void setServices(MasterServices srvc) {<a name="line.1319"></a>
-<span class="sourceLineNo">1320</span>      this.services = srvc;<a name="line.1320"></a>
-<span class="sourceLineNo">1321</span>    }<a name="line.1321"></a>
-<span class="sourceLineNo">1322</span><a name="line.1322"></a>
-<span class="sourceLineNo">1323</span>    @Override<a name="line.1323"></a>
-<span class="sourceLineNo">1324</span>    void init(Cluster cluster) {<a name="line.1324"></a>
-<span class="sourceLineNo">1325</span>      super.init(cluster);<a name="line.1325"></a>
-<span class="sourceLineNo">1326</span>      locality = 0.0;<a name="line.1326"></a>
-<span class="sourceLineNo">1327</span>      bestLocality = 0.0;<a name="line.1327"></a>
-<span class="sourceLineNo">1328</span><a name="line.1328"></a>
-<span class="sourceLineNo">1329</span>      // If no master, no computation will work, so assume 0 cost<a name="line.1329"></a>
-<span class="sourceLineNo">1330</span>      if (this.services == null) {<a name="line.1330"></a>
-<span class="sourceLineNo">1331</span>        return;<a name="line.1331"></a>
-<span class="sourceLineNo">1332</span>      }<a name="line.1332"></a>
-<span class="sourceLineNo">1333</span><a name="line.1333"></a>
-<span class="sourceLineNo">1334</span>      for (int region = 0; region &lt; cluster.numRegions; region++) {<a name="line.1334"></a>
-<span class="sourceLineNo">1335</span>        locality += getWeightedLocality(region, regionIndexToEntityIndex(region));<a name="line.1335"></a>
-<span class="sourceLineNo">1336</span>        bestLocality += getWeightedLocality(region, getMostLocalEntityForRegion(region));<a name="line.1336"></a>
-<span class="sourceLineNo">1337</span>      }<a name="line.1337"></a>
-<span class="sourceLineNo">1338</span><a name="line.1338"></a>
-<span class="sourceLineNo">1339</span>      // We normalize locality to be a score between 0 and 1.0 representing how good it<a name="line.1339"></a>
-<span class="sourceLineNo">1340</span>      // is compared to how good it could be. If bestLocality is 0, assume locality is 100<a name="line.1340"></a>
-<span class="sourceLineNo">1341</span>      // (and the cost is 0)<a name="line.1341"></a>
-<span class="sourceLineNo">1342</span>      locality = bestLocality == 0 ? 1.0 : locality / bestLocality;<a name="line.1342"></a>
-<span class="sourceLineNo">1343</span>    }<a name="line.1343"></a>
-<span class="sourceLineNo">1344</span><a name="line.1344"></a>
-<span class="sourceLineNo">1345</span>    @Override<a name="line.1345"></a>
-<span class="sourceLineNo">1346</span>    protected void regionMoved(int region, int oldServer, int newServer) {<a name="line.1346"></a>
-<span class="sourceLineNo">1347</span>      int oldEntity = type == LocalityType.SERVER ? oldServer : cluster.serverIndexToRackIndex[oldServer];<a name="line.1347"></a>
-<span class="sourceLineNo">1348</span>      int newEntity = type == LocalityType.SERVER ? newServer : cluster.serverIndexToRackIndex[newServer];<a name="line.1348"></a>
-<span class="sourceLineNo">1349</span>      if (this.services == null) {<a name="line.1349"></a>
-<span class="sourceLineNo">1350</span>        return;<a name="line.1350"></a>
-<span class="sourceLineNo">1351</span>      }<a name="line.1351"></a>
-<span class="sourceLineNo">1352</span>      double localityDelta = getWeightedLocality(region, newEntity) - getWeightedLocality(region, oldEntity);<a name="line.1352"></a>
-<span class="sourceLineNo">1353</span>      double normalizedDelta = bestLocality == 0 ? 0.0 : localityDelta / bestLocality;<a name="line.1353"></a>
-<span class="sourceLineNo">1354</span>      locality += normalizedDelta;<a name="line.1354"></a>
-<span class="sourceLineNo">1355</span>    }<a name="line.1355"></a>
-<span class="sourceLineNo">1356</span><a name="line.1356"></a>
-<span class="sourceLineNo">1357</span>    @Override<a name="line.1357"></a>
-<span class="sourceLineNo">1358</span>    protected double cost() {<a name="line.1358"></a>
-<span class="sourceLineNo">1359</span>      return 1 - locality;<a name="line.1359"></a>
-<span class="sourceLineNo">1360</span>    }<a name="line.1360"></a>
-<span class="sourceLineNo">1361</span><a name="line.1361"></a>
-<span class="sourceLineNo">1362</span>    private int getMostLocalEntityForRegion(int region) {<a name="line.1362"></a>
-<span class="sourceLineNo">1363</span>      return cluster.getOrComputeRegionsToMostLocalEntities(type)[region];<a name="line.1363"></a>
-<span class="sourceLineNo">1364</span>    }<a name="line.1364"></a>
-<span class="sourceLineNo">1365</span><a name="line.1365"></a>
-<span class="sourceLineNo">1366</span>    private double getWeightedLocality(int region, int entity) {<a name="line.1366"></a>
-<span class="sourceLineNo">1367</span>      return cluster.getOrComputeWeightedLocality(region, entity, type);<a name="line.1367"></a>
-<span class="sourceLineNo">1368</span>    }<a name="line.1368"></a>
-<span class="sourceLineNo">1369</span><a name="line.1369"></a>
-<span class="sourceLineNo">1370</span>  }<a name="line.1370"></a>
+<span class="sourceLineNo">1301</span>    private MasterServices services;<a name="line.1301"></a>
+<span class="sourceLineNo">1302</span><a name="line.1302"></a>
+<span class="sourceLineNo">1303</span>    LocalityBasedCostFunction(Configuration conf,<a name="line.1303"></a>
+<span class="sourceLineNo">1304</span>                              MasterServices srv,<a name="line.1304"></a>
+<span class="sourceLineNo">1305</span>                              LocalityType type,<a name="line.1305"></a>
+<span class="sourceLineNo">1306</span>                              String localityCostKey,<a name="line.1306"></a>
+<span class="sourceLineNo">1307</span>                              float defaultLocalityCost) {<a name="line.1307"></a>
+<span class="sourceLineNo">1308</span>      super(conf);<a name="line.1308"></a>
+<span class="sourceLineNo">1309</span>      this.type = type;<a name="line.1309"></a>
+<span class="sourceLineNo">1310</span>      this.setMultiplier(conf.getFloat(localityCostKey, defaultLocalityCost));<a name="line.1310"></a>
+<span class="sourceLineNo">1311</span>      this.services = srv;<a name="line.1311"></a>
+<span class="sourceLineNo">1312</span>      this.locality = 0.0;<a name="line.1312"></a>
+<span class="sourceLineNo">1313</span>      this.bestLocality = 0.0;<a name="line.1313"></a>
+<span class="sourceLineNo">1314</span>    }<a name="line.1314"></a>
+<span class="sourceLineNo">1315</span><a name="line.1315"></a>
+<span class="sourceLineNo">1316</span>    /**<a name="line.1316"></a>
+<span class="sourceLineNo">1317</span>     * Maps region to the current entity (server or rack) on which it is stored<a name="line.1317"></a>
+<span class="sourceLineNo">1318</span>     */<a name="line.1318"></a>
+<span class="sourceLineNo">1319</span>    abstract int regionIndexToEntityIndex(int region);<a name="line.1319"></a>
+<span class="sourceLineNo">1320</span><a name="line.1320"></a>
+<span class="sourceLineNo">1321</span>    public void setServices(MasterServices srvc) {<a name="line.1321"></a>
+<span class="sourceLineNo">1322</span>      this.services = srvc;<a name="line.1322"></a>
+<span class="sourceLineNo">1323</span>    }<a name="line.1323"></a>
+<span class="sourceLineNo">1324</span><a name="line.1324"></a>
+<span class="sourceLineNo">1325</span>    @Override<a name="line.1325"></a>
+<span class="sourceLineNo">1326</span>    void init(Cluster cluster) {<a name="line.1326"></a>
+<span class="sourceLineNo">1327</span>      super.init(cluster);<a name="line.1327"></a>
+<span class="sourceLineNo">1328</span>      locality = 0.0;<a name="line.1328"></a>
+<span class="sourceLineNo">1329</span>      bestLocality = 0.0;<a name="line.1329"></a>
+<span class="sourceLineNo">1330</span><a name="line.1330"></a>
+<span class="sourceLineNo">1331</span>      // If no master, no computation will work, so assume 0 cost<a name="line.1331"></a>
+<span class="sourceLineNo">1332</span>      if (this.services == null) {<a name="line.1332"></a>
+<span class="sourceLineNo">1333</span>        return;<a name="line.1333"></a>
+<span class="sourceLineNo">1334</span>      }<a name="line.1334"></a>
+<span class="sourceLineNo">1335</span><a name="line.1335"></a>
+<span class="sourceLineNo">1336</span>      for (int region = 0; region &lt; cluster.numRegions; region++) {<a name="line.1336"></a>
+<span class="sourceLineNo">1337</span>        locality += getWeightedLocality(region, regionIndexToEntityIndex(region));<a name="line.1337"></a>
+<span class="sourceLineNo">1338</span>        bestLocality += getWeightedLocality(region, getMostLocalEntityForRegion(region));<a name="line.1338"></a>
+<span class="sourceLineNo">1339</span>      }<a name="line.1339"></a>
+<span class="sourceLineNo">1340</span><a name="line.1340"></a>
+<span class="sourceLineNo">1341</span>      // We normalize locality to be a score between 0 and 1.0 representing how good it<a name="line.1341"></a>
+<span class="sourceLineNo">1342</span>      // is compared to how good it could be. If bestLocality is 0, assume locality is 100<a name="line.1342"></a>
+<span class="sourceLineNo">1343</span>      // (and the cost is 0)<a name="line.1343"></a>
+<span class="sourceLineNo">1344</span>      locality = bestLocality == 0 ? 1.0 : locality / bestLocality;<a name="line.1344"></a>
+<span class="sourceLineNo">1345</span>    }<a name="line.1345"></a>
+<span class="sourceLineNo">1346</span><a name="line.1346"></a>
+<span class="sourceLineNo">1347</span>    @Override<a name="line.1347"></a>
+<span class="sourceLineNo">1348</span>    protected void regionMoved(int region, int oldServer, int newServer) {<a name="line.1348"></a>
+<span class="sourceLineNo">1349</span>      int oldEntity = type == LocalityType.SERVER ? oldServer : cluster.serverIndexToRackIndex[oldServer];<a name="line.1349"></a>
+<span class="sourceLineNo">1350</span>      int newEntity = type == LocalityType.SERVER ? newServer : cluster.serverIndexToRackIndex[newServer];<a name="line.1350"></a>
+<span class="sourceLineNo">1351</span>      if (this.services == null) {<a name="line.1351"></a>
+<span class="sourceLineNo">1352</span>        return;<a name="line.1352"></a>
+<span class="sourceLineNo">1353</span>      }<a name="line.1353"></a>
+<span class="sourceLineNo">1354</span>      double localityDelta = getWeightedLocality(region, newEntity) - getWeightedLocality(region, oldEntity);<a name="line.1354"></a>
+<span class="sourceLineNo">1355</span>      double normalizedDelta = bestLocality == 0 ? 0.0 : localityDelta / bestLocality;<a name="line.1355"></a>
+<span class="sourceLineNo">1356</span>      locality += normalizedDelta;<a name="line.1356"></a>
+<span class="sourceLineNo">1357</span>    }<a name="line.1357"></a>
+<span class="sourceLineNo">1358</span><a name="line.1358"></a>
+<span class="sourceLineNo">1359</span>    @Override<a name="line.1359"></a>
+<span class="sourceLineNo">1360</span>    protected double cost() {<a name="line.1360"></a>
+<span class="sourceLineNo">1361</span>      return 1 - locality;<a name="line.1361"></a>
+<span class="sourceLineNo">1362</span>    }<a name="line.1362"></a>
+<span class="sourceLineNo">1363</span><a name="line.1363"></a>
+<span class="sourceLineNo">1364</span>    private int getMostLocalEntityForRegion(int region) {<a name="line.1364"></a>
+<span class="sourceLineNo">1365</span>      return cluster.getOrComputeRegionsToMostLocalEntities(type)[region];<a name="line.1365"></a>
+<span class="sourceLineNo">1366</span>    }<a name="line.1366"></a>
+<span class="sourceLineNo">1367</span><a name="line.1367"></a>
+<span class="sourceLineNo">1368</span>    private double getWeightedLocality(int region, int entity) {<a name="line.1368"></a>
+<span class="sourceLineNo">1369</span>      return cluster.getOrComputeWeightedLocality(region, entity, type);<a name="line.1369"></a>
+<span class="sourceLineNo">1370</span>    }<a name="line.1370"></a>
 <span class="sourceLineNo">1371</span><a name="line.1371"></a>
-<span class="sourceLineNo">1372</span>  static class ServerLocalityCostFunction extends LocalityBasedCostFunction {<a name="line.1372"></a>
+<span class="sourceLineNo">1372</span>  }<a name="line.1372"></a>
 <span class="sourceLineNo">1373</span><a name="line.1373"></a>
-<span class="sourceLineNo">1374</span>    private static final String LOCALITY_COST_KEY = "hbase.master.balancer.stochastic.localityCost";<a name="line.1374"></a>
-<span class="sourceLineNo">1375</span>    private static final float DEFAULT_LOCALITY_COST = 25;<a name="line.1375"></a>
-<span class="sourceLineNo">1376</span><a name="line.1376"></a>
-<span class="sourceLineNo">1377</span>    ServerLocalityCostFunction(Configuration conf, MasterServices srv) {<a name="line.1377"></a>
-<span class="sourceLineNo">1378</span>      super(<a name="line.1378"></a>
-<span class="sourceLineNo">1379</span>          conf,<a name="line.1379"></a>
-<span class="sourceLineNo">1380</span>          srv,<a name="line.1380"></a>
-<span class="sourceLineNo">1381</span>          LocalityType.SERVER,<a name="line.1381"></a>
-<span class="sourceLineNo">1382</span>          LOCALITY_COST_KEY,<a name="line.1382"></a>
-<span class="sourceLineNo">1383</span>          DEFAULT_LOCALITY_COST<a name="line.1383"></a>
-<span class="sourceLineNo">1384</span>      );<a name="line.1384"></a>
-<span class="sourceLineNo">1385</span>    }<a name="line.1385"></a>
-<span class="sourceLineNo">1386</span><a name="line.1386"></a>
-<span class="sourceLineNo">1387</span>    @Override<a name="line.1387"></a>
-<span class="sourceLineNo">1388</span>    int regionIndexToEntityIndex(int region) {<a name="line.1388"></a>
-<span class="sourceLineNo">1389</span>      return cluster.regionIndexToServerIndex[region];<a name="line.1389"></a>
-<span class="sourceLineNo">1390</span>    }<a name="line.1390"></a>
-<span class="sourceLineNo">1391</span>  }<a name="line.1391"></a>
-<span class="sourceLineNo">1392</span><a name="line.1392"></a>
-<span class="sourceLineNo">1393</span>  static class RackLocalityCostFunction extends LocalityBasedCostFunction {<a name="line.1393"></a>
+<span class="sourceLineNo">1374</span>  static class ServerLocalityCostFunction extends LocalityBasedCostFunction {<a name="line.1374"></a>
+<span class="sourceLineNo">1375</span><a name="line.1375"></a>
+<span class="sourceLineNo">1376</span>    private static final String LOCALITY_COST_KEY = "hbase.master.balancer.stochastic.localityCost";<a name="line.1376"></a>
+<span class="sourceLineNo">1377</span>    private static final float DEFAULT_LOCALITY_COST = 25;<a name="line.1377"></a>
+<span class="sourceLineNo">1378</span><a name="line.1378"></a>
+<span class="sourceLineNo">1379</span>    ServerLocalityCostFunction(Configuration conf, MasterServices srv) {<a name="line.1379"></a>
+<span class="sourceLineNo">1380</span>      super(<a name="line.1380"></a>
+<span class="sourceLineNo">1381</span>          conf,<a name="line.1381"></a>
+<span class="sourceLineNo">1382</span>          srv,<a name="line.1382"></a>
+<span class="sourceLineNo">1383</span>          LocalityType.SERVER,<a name="line.1383"></a>
+<span class="sourceLineNo">1384</span>          LOCALITY_COST_KEY,<a name="line.1384"></a>
+<span class="sourceLineNo">1385</span>          DEFAULT_LOCALITY_COST<a name="line.1385"></a>
+<span class="sourceLineNo">1386</span>      );<a name="line.1386"></a>
+<span class="sourceLineNo">1387</span>    }<a name="line.1387"></a>
+<span class="sourceLineNo">1388</span><a name="line.1388"></a>
+<span class="sourceLineNo">1389</span>    @Override<a name="line.1389"></a>
+<span class="sourceLineNo">1390</span>    int regionIndexToEntityIndex(int region) {<a name="line.1390"></a>
+<span class="sourceLineNo">1391</span>      return cluster.regionIndexToServerIndex[region];<a name="line.1391"></a>
+<span class="sourceLineNo">1392</span>    }<a name="line.1392"></a>
+<span class="sourceLineNo">1393</span>  }<a name="line.1393"></a>
 <span class="sourceLineNo">1394</span><a name="line.1394"></a>
-<span class="sourceLineNo">1395</span>    private static final String RACK_LOCALITY_COST_KEY = "hbase.master.balancer.stochastic.rackLocalityCost";<a name="line.1395"></a>
-<span class="sourceLineNo">1396</span>    private static final float DEFAULT_RACK_LOCALITY_COST = 15;<a name="line.1396"></a>
-<span class="sourceLineNo">1397</span><a name="line.1397"></a>
-<span class="sourceLineNo">1398</span>    public RackLocalityCostFunction(Configuration conf, MasterServices services) {<a name="line.1398"></a>
-<span class="sourceLineNo">1399</span>      super(<a name="line.1399"></a>
-<span class="sourceLineNo">1400</span>          conf,<a name="line.1400"></a>
-<span class="sourceLineNo">1401</span>          services,<a name="line.1401"></a>
-<span class="sourceLineNo">1402</span>          LocalityType.RACK,<a name="line.1402"></a>
-<span class="sourceLineNo">1403</span>          RACK_LOCALITY_COST_KEY,<a name="line.1403"></a>
-<span class="sourceLineNo">1404</span>          DEFAULT_RACK_LOCALITY_COST<a name="line.1404"></a>
-<span class="sourceLineNo">1405</span>      );<a name="line.1405"></a>
-<span class="sourceLineNo">1406</span>    }<a name="line.1406"></a>
-<span class="sourceLineNo">1407</span><a name="line.1407"></a>
-<span class="sourceLineNo">1408</span>    @Override<a name="line.1408"></a>
-<span class="sourceLineNo">1409</span>    int regionIndexToEntityIndex(int region) {<a name="line.1409"></a>
-<span class="sourceLineNo">1410</span>      return cluster.getRackForRegion(region);<a name="line.1410"></a>
-<span class="sourceLineNo">1411</span>    }<a name="line.1411"></a>
-<span class="sourceLineNo">1412</span>  }<a name="line.1412"></a>
-<span class="sourceLineNo">1413</span><a name="line.1413"></a>
-<span class="sourceLineNo">1414</span>  /**<a name="line.1414"></a>
-<span class="sourceLineNo">1415</span>   * Base class the allows writing costs functions from rolling average of some<a name="line.1415"></a>
-<span class="sourceLineNo">1416</span>   * number from RegionLoad.<a name="line.1416"></a>
-<span class="sourceLineNo">1417</span>   */<a name="line.1417"></a>
-<span class="sourceLineNo">1418</span>  abstract static class CostFromRegionLoadFunction extends CostFunction {<a name="line.1418"></a>
-<span class="sourceLineNo">1419</span><a name="line.1419"></a>
-<span class="sourceLineNo">1420</span>    private ClusterMetrics clusterStatus = null;<a name="line.1420"></a>
-<span class="sourceLineNo">1421</span>    private Map&lt;String, Deque&lt;BalancerRegionLoad&gt;&gt; loads = null;<a name="line.1421"></a>
-<span class="sourceLineNo">1422</span>    private double[] stats = null;<a name="line.1422"></a>
-<span class="sourceLineNo">1423</span>    CostFromRegionLoadFunction(Configuration conf) {<a name="line.1423"></a>
-<span class="sourceLineNo">1424</span>      super(conf);<a name="line.1424"></a>
-<span class="sourceLineNo">1425</span>    }<a name="line.1425"></a>
-<span class="sourceLineNo">1426</span><a name="line.1426"></a>
-<span class="sourceLineNo">1427</span>    void setClusterMetrics(ClusterMetrics status) {<a name="line.1427"></a>
-<span class="sourceLineNo">1428</span>      this.clusterStatus = status;<a name="line.1428"></a>
-<span class="sourceLineNo">1429</span>    }<a name="line.1429"></a>
-<span class="sourceLineNo">1430</span><a name="line.1430"></a>
-<span class="sourceLineNo">1431</span>    void setLoads(Map&lt;String, Deque&lt;BalancerRegionLoad&gt;&gt; l) {<a name="line.1431"></a>
-<span class="sourceLineNo">1432</span>      this.loads = l;<a name="line.1432"></a>
-<span class="sourceLineNo">1433</span>    }<a name="line.1433"></a>
-<span class="sourceLineNo">1434</span><a name="line.1434"></a>
-<span class="sourceLineNo">1435</span>    @Override<a name="line.1435"></a>
-<span class="sourceLineNo">1436</span>    protected double cost() {<a name="line.1436"></a>
-<span class="sourceLineNo">1437</span>      if (clusterStatus == null || loads == null) {<a name="line.1437"></a>
-<span class="sourceLineNo">1438</span>        return 0;<a name="line.1438"></a>
-<span class="sourceLineNo">1439</span>      }<a name="line.1439"></a>
-<span class="sourceLineNo">1440</span><a name="line.1440"></a>
-<span class="sourceLineNo">1441</span>      if (stats == null || stats.length != cluster.numServers) {<a name="line.1441"></a>
-<span class="sourceLineNo">1442</span>        stats = new double[cluster.numServers];<a name="line.1442"></a>
-<span class="sourceLineNo">1443</span>      }<a name="line.1443"></a>
-<span class="sourceLineNo">1444</span><a name="line.1444"></a>
-<span class="sourceLineNo">1445</span>      for (int i =0; i &lt; stats.length; i++) {<a name="line.1445"></a>
-<span class="sourceLineNo">1446</span>        //Cost this server has from RegionLoad<a name="line.1446"></a>
-<span class="sourceLineNo">1447</span>        long cost = 0;<a name="line.1447"></a>
-<span class="sourceLineNo">1448</span><a name="line.1448"></a>
-<span class="sourceLineNo">1449</span>        // for every region on this server get the rl<a name="line.1449"></a>
-<span class="sourceLineNo">1450</span>        for(int regionIndex:cluster.regionsPerServer[i]) {<a name="line.1450"></a>
-<span class="sourceLineNo">1451</span>          Collection&lt;BalancerRegionLoad&gt; regionLoadList =  cluster.regionLoads[regionIndex];<a name="line.1451"></a>
-<span class="sourceLineNo">1452</span><a name="line.1452"></a>
-<span class="sourceLineNo">1453</span>          // Now if we found a region load get the type of cost that was requested.<a name="line.1453"></a>
-<span class="sourceLineNo">1454</span>          if (regionLoadList != null) {<a name="line.1454"></a>
-<span class="sourceLineNo">1455</span>            cost = (long) (cost + getRegionLoadCost(regionLoadList));<a name="line.1455"></a>
-<span class="sourceLineNo">1456</span>          }<a name="line.1456"></a>
-<span class="sourceLineNo">1457</span>        }<a name="line.1457"></a>
-<span class="sourceLineNo">1458</span><a name="line.1458"></a>
-<span class="sourceLineNo">1459</span>        // Add the total cost to the stats.<a name="line.1459"></a>
-<span class="sourceLineNo">1460</span>        stats[i] = cost;<a name="line.1460"></a>
-<span class="sourceLineNo">1461</span>      }<a name="line.1461"></a>
-<span class="sourceLineNo">1462</span><a name="line.1462"></a>
-<span class="sourceLineNo">1463</span>      // Now return the scaled cost from data held in the stats object.<a name="line.1463"></a>
-<span class="sourceLineNo">1464</span>      return costFromArray(stats);<a name="line.1464"></a>
-<span class="sourceLineNo">1465</span>    }<a name="line.1465"></a>
-<span class="sourceLineNo">1466</span><a name="line.1466"></a>
-<span class="sourceLineNo">1467</span>    protected double getRegionLoadCost(Collection&lt;BalancerRegionLoad&gt; regionLoadList) {<a name="line.1467"></a>
-<span class="sourceLineNo">1468</span>      double cost = 0;<a name="line.1468"></a>
-<span class="sourceLineNo">1469</span>      for (BalancerRegionLoad rl : regionLoadList) {<a name="line.1469"></a>
-<span class="sourceLineNo">1470</span>        cost += getCostFromRl(rl);<a name="line.1470"></a>
-<span class="sourceLineNo">1471</span>      }<a name="line.1471"></a>
-<span class="sourceLineNo">1472</span>      return cost / regionLoadList.size();<a name="line.1472"></a>
-<span class="sourceLineNo">1473</span>    }<a name="line.1473"></a>
-<span class="sourceLineNo">1474</span><a name="line.1474"></a>
-<span class="sourceLineNo">1475</span>    protected abstract double getCostFromRl(BalancerRegionLoad rl);<a name="line.1475"></a>
-<span class="sourceLineNo">1476</span>  }<a name="line.1476"></a>
-<span class="sourceLineNo">1477</span><a name="line.1477"></a>
-<span class="sourceLineNo">1478</span>  /**<a name="line.1478"></a>
-<span class="sourceLineNo">1479</span>   * Class to be used for the subset of RegionLoad costs that should be treated as rates.<a name="line.1479"></a>
-<span class="sourceLineNo">1480</span>   * We do not compare about the actual rate in requests per second but rather the rate relative<a name="line.1480"></a>
-<span class="sourceLineNo">1481</span>   * to the rest of the regions.<a name="line.1481"></a>
-<span class="sourceLineNo">1482</span>   */<a name="line.1482"></a>
-<span class="sourceLineNo">1483</span>  abstract static class CostFromRegionLoadAsRateFunction extends CostFromRegionLoadFunction {<a name="line.1483"></a>
-<span class="sourceLineNo">1484</span><a name="line.1484"></a>
-<span class="sourceLineNo">1485</span>    CostFromRegionLoadAsRateFunction(Configuration conf) {<a name="line.1485"></a>
-<span class="sourceLineNo">1486</span>      super(conf);<a name="line.1486"></a>
-<span class="sourceLineNo">1487</span>    }<a name="line.1487"></a>
-<span class="sourceLineNo">1488</span><a name="line.1488"></a>
-<span class="sourceLineNo">1489</span>    @Override<a name="line.1489"></a>
-<span class="sourceLineNo">1490</span>    protected double getRegionLoadCost(Collection&lt;BalancerRegionLoad&gt; regionLoadList) {<a name="line.1490"></a>
-<span class="sourceLineNo">1491</span>      double cost = 0;<a name="line.1491"></a>
-<span class="sourceLineNo">1492</span>      double previous = 0;<a name="line.1492"></a>
-<span class="sourceLineNo">1493</span>      boolean isFirst = true;<a name="line.1493"></a>
-<span class="sourceLineNo">1494</span>      for (BalancerRegionLoad rl : regionLoadList) {<a name="line.1494"></a>
-<span class="sourceLineNo">1495</span>        double current = getCostFromRl(rl);<a name="line.1495"></a>
-<span class="sourceLineNo">1496</span>        if (isFirst) {<a name="line.1496"></a>
-<span class="sourceLineNo">1497</span>          isFirst = false;<a name="line.1497"></a>
-<span class="sourceLineNo">1498</span>        } else {<a name="line.1498"></a>
-<span class="sourceLineNo">1499</span>          cost += current - previous;<a name="line.1499"></a>
-<span class="sourceLineNo">1500</span>        }<a name="line.1500"></a>
-<span class="sourceLineNo">1501</span>        previous = current;<a name="line.1501"></a>
-<span class="sourceLineNo">1502</span>      }<a name="line.1502"></a>
-<span class="sourceLineNo">1503</span>      return Math.max(0, cost / (regionLoadList.size() - 1));<a name="line.1503"></a>
-<span class="sourceLineNo">1504</span>    }<a name="line.1504"></a>
-<span class="sourceLineNo">1505</span>  }<a name="line.1505"></a>
-<span class="sourceLineNo">1506</span><a name="line.1506"></a>
-<span class="sourceLineNo">1507</span>  /**<a name="line.1507"></a>
-<span class="sourceLineNo">1508</span>   * Compute the cost of total number of read requests  The more unbalanced the higher the<a name="line.1508"></a>
-<span class="sourceLineNo">1509</span>   * computed cost will be.  This uses a rolling average of regionload.<a name="line.1509"></a>
-<span class="sourceLineNo">1510</span>   */<a name="line.1510"></a>
-<span class="sourceLineNo">1511</span><a name="line.1511"></a>
-<span class="sourceLineNo">1512</span>  static class ReadRequestCostFunction extends CostFromRegionLoadAsRateFunction {<a name="line.1512"></a>
+<span class="sourceLineNo">1395</span>  static class RackLocalityCostFunction extends LocalityBasedCostFunction {<a name="line.1395"></a>
+<span class="sourceLineNo">1396</span><a name="line.1396"></a>
+<span class="sourceLineNo">1397</span>    private static final String RACK_LOCALITY_COST_KEY = "hbase.master.balancer.stochastic.rackLocalityCost";<a name="line.1397"></a>
+<span class="sourceLineNo">1398</span>    private static final float DEFAULT_RACK_LOCALITY_COST = 15;<a name="line.1398"></a>
+<span class="sourceLineNo">1399</span><a name="line.1399"></a>
+<span class="sourceLineNo">1400</span>    public RackLocalityCostFunction(Configuration conf, MasterServices services) {<a name="line.1400"></a>
+<span class="sourceLineNo">1401</span>      super(<a name="line.1401"></a>
+<span class="sourceLineNo">1402</span>          conf,<a name="line.1402"></a>
+<span class="sourceLineNo">1403</span>          services,<a name="line.1403"></a>
+<span class="sourceLineNo">1404</span>          LocalityType.RACK,<a name="line.1404"></a>
+<span class="sourceLineNo">1405</span>          RACK_LOCALITY_COST_KEY,<a name="line.1405"></a>
+<span class="sourceLineNo">1406</span>          DEFAULT_RACK_LOCALITY_COST<a name="line.1406"></a>
+<span class="sourceLineNo">1407</span>      );<a name="line.1407"></a>
+<span class="sourceLineNo">1408</span>    }<a name="line.1408"></a>
+<span class="sourceLineNo">1409</span><a name="line.1409"></a>
+<span class="sourceLineNo">1410</span>    @Override<a name="line.1410"></a>
+<span class="sourceLineNo">1411</span>    int regionIndexToEntityIndex(int region) {<a name="line.1411"></a>
+<span class="sourceLineNo">1412</span>      return cluster.getRackForRegion(region);<a name="line.1412"></a>
+<span class="sourceLineNo">1413</span>    }<a name="line.1413"></a>
+<span class="sourceLineNo">1414</span>  }<a name="line.1414"></a>
+<span class="sourceLineNo">1415</span><a name="line.1415"></a>
+<span class="sourceLineNo">1416</span>  /**<a name="line.1416"></a>
+<span class="sourceLineNo">1417</span>   * Base class the allows writing costs functions from rolling average of some<a name="line.1417"></a>
+<span class="sourceLineNo">1418</span>   * number from RegionLoad.<a name="line.1418"></a>
+<span class="sourceLineNo">1419</span>   */<a name="line.1419"></a>
+<span class="sourceLineNo">1420</span>  abstract static class CostFromRegionLoadFunction extends CostFunction {<a name="line.1420"></a>
+<span class="sourceLineNo">1421</span><a name="line.1421"></a>
+<span class="sourceLineNo">1422</span>    private ClusterMetrics clusterStatus = null;<a name="line.1422"></a>
+<span class="sourceLineNo">1423</span>    private Map&lt;String, Deque&lt;BalancerRegionLoad&gt;&gt; loads = null;<a name="line.1423"></a>
+<span class="sourceLineNo">1424</span>    private double[] stats = null;<a name="line.1424"></a>
+<span class="sourceLineNo">1425</span>    CostFromRegionLoadFunction(Configuration conf) {<a name="line.1425"></a>
+<span class="sourceLineNo">1426</span>      super(conf);<a name="line.1426"></a>
+<span class="sourceLineNo">1427</span>    }<a name="line.1427"></a>
+<span class="sourceLineNo">1428</span><a name="line.1428"></a>
+<span class="sourceLineNo">1429</span>    void setClusterMetrics(ClusterMetrics status) {<a name="line.1429"></a>
+<span class="sourceLineNo">1430</span>      this.clusterStatus = status;<a name="line.1430"></a>
+<span class="sourceLineNo">1431</span>    }<a name="line.1431"></a>
+<span class="sourceLineNo">1432</span><a name="line.1432"></a>
+<span class="sourceLineNo">1433</span>    void setLoads(Map&lt;String, Deque&lt;BalancerRegionLoad&gt;&gt; l) {<a name="line.1433"></a>
+<span class="sourceLineNo">1434</span>      this.loads = l;<a name="line.1434"></a>
+<span class="sourceLineNo">1435</span>    }<a name="line.1435"></a>
+<span class="sourceLineNo">1436</span><a name="line.1436"></a>
+<span class="sourceLineNo">1437</span>    @Override<a name="line.1437"></a>
+<span class="sourceLineNo">1438</span>    protected double cost() {<a name="line.1438"></a>
+<span class="sourceLineNo">1439</span>      if (clusterStatus == null || loads == null) {<a name="line.1439"></a>
+<span class="sourceLineNo">1440</span>        return 0;<a name="line.1440"></a>
+<span class="sourceLineNo">1441</span>      }<a name="line.1441"></a>
+<span class="sourceLineNo">1442</span><a name="line.1442"></a>
+<span class="sourceLineNo">1443</span>      if (stats == null || stats.length != cluster.numServers) {<a name="line.1443"></a>
+<span class="sourceLineNo">1444</span>        stats = new double[cluster.numServers];<a name="line.1444"></a>
+<span class="sourceLineNo">1445</span>      }<a name="line.1445"></a>
+<span class="sourceLineNo">1446</span><a name="line.1446"></a>
+<span class="sourceLineNo">1447</span>      for (int i =0; i &lt; stats.length; i++) {<a name="line.1447"></a>
+<span class="sourceLineNo">1448</span>        //Cost this server has from RegionLoad<a name="line.1448"></a>
+<span class="sourceLineNo">1449</span>        long cost = 0;<a name="line.1449"></a>
+<span class="sourceLineNo">1450</span><a name="line.1450"></a>
+<span class="sourceLineNo">1451</span>        // for every region on this server get the rl<a name="line.1451"></a>
+<span class="sourceLineNo">1452</span>        for(int regionIndex:cluster.regionsPerServer[i]) {<a name="line.1452"></a>
+<span class="sourceLineNo">1453</span>          Collection&lt;BalancerRegionLoad&gt; regionLoadList =  cluster.regionLoads[regionIndex];<a name="line.1453"></a>
+<span class="sourceLineNo">1454</span><a name="line.1454"></a>
+<span class="sourceLineNo">1455</span>          // Now if we found a region load get the type of cost that was requested.<a name="line.1455"></a>
+<span class="sourceLineNo">1456</span>          if (regionLoadList != null) {<a name="line.1456"></a>
+<span class="sourceLineNo">1457</span>            cost = (long) (cost + getRegionLoadCost(regionLoadList));<a name="line.1457"></a>
+<span class="sourceLineNo">1458</span>          }<a name="line.1458"></a>
+<span class="sourceLineNo">1459</span>        }<a name="line.1459"></a>
+<span class="sourceLineNo">1460</span><a name="line.1460"></a>
+<span class="sourceLineNo">1461</span>        // Add the total cost to the stats.<a name="line.1461"></a>
+<span class="sourceLineNo">1462</span>        stats[i] = cost;<a name="line.1462"></a>
+<span class="sourceLineNo">1463</span>      }<a name="line.1463"></a>
+<span class="sourceLineNo">1464</span><a name="line.1464"></a>
+<span class="sourceLineNo">1465</span>      // Now return the scaled cost from data held in the stats object.<a name="line.1465"></a>
+<span class="sourceLineNo">1466</span>      return costFromArray(stats);<a name="line.1466"></a>
+<span class="sourceLineNo">1467</span>    }<a name="line.1467"></a>
+<span class="sourceLineNo">1468</span><a name="line.1468"></a>
+<span class="sourceLineNo">1469</span>    protected double getRegionLoadCost(Collection&lt;BalancerRegionLoad&gt; regionLoadList) {<a name="line.1469"></a>
+<span class="sourceLineNo">1470</span>      double cost = 0;<a name="line.1470"></a>
+<span class="sourceLineNo">1471</span>      for (BalancerRegionLoad rl : regionLoadList) {<a name="line.1471"></a>
+<span class="sourceLineNo">1472</span>        cost += getCostFromRl(rl);<a name="line.1472"></a>
+<span class="sourceLineNo">1473</span>      }<a name="line.1473"></a>
+<span class="sourceLineNo">1474</span>      return cost / regionLoadList.size();<a name="line.1474"></a>
+<span class="sourceLineNo">1475</span>    }<a name="line.1475"></a>
+<span class="sourceLineNo">1476</span><a name="line.1476"></a>
+<span class="sourceLineNo">1477</span>    protected abstract double getCostFromRl(BalancerRegionLoad rl);<a name="line.1477"></a>
+<span class="sourceLineNo">1478</span>  }<a name="line.1478"></a>
+<span class="sourceLineNo">1479</span><a name="line.1479"></a>
+<span class="sourceLineNo">1480</span>  /**<a name="line.1480"></a>
+<span class="sourceLineNo">1481</span>   * Class to be used for the subset of RegionLoad costs that should be treated as rates.<a name="line.1481"></a>
+<span class="sourceLineNo">1482</span>   * We do not compare about the actual rate in requests per second but rather the rate relative<a name="line.1482"></a>
+<span class="sourceLineNo">1483</span>   * to the rest of the regions.<a name="line.1483"></a>
+<span class="sourceLineNo">1484</span>   */<a name="line.1484"></a>
+<span class="sourceLineNo">1485</span>  abstract static class CostFromRegionLoadAsRateFunction extends CostFromRegionLoadFunction {<a name="line.1485"></a>
+<span class="sourceLineNo">1486</span><a name="line.1486"></a>
+<span class="sourceLineNo">1487</span>    CostFromRegionLoadAsRateFunction(Configuration conf) {<a name="line.1487"></a>
+<span class="sourceLineNo">1488</span>      super(conf);<a name="line.1488"></a>
+<span class="sourceLineNo">1489</span>    }<a name="line.1489"></a>
+<span class="sourceLineNo">1490</span><a name="line.1490"></a>
+<span class="sourceLineNo">1491</span>    @Override<a name="line.1491"></a>
+<span class="sourceLineNo">1492</span>    protected double getRegionLoadCost(Collection&lt;BalancerRegionLoad&gt; regionLoadList) {<a name="line.1492"></a>
+<span class="sourceLineNo">1493</span>      double cost = 0;<a name="line.1493"></a>
+<span class="sourceLineNo">1494</span>      double previous = 0;<a name="line.1494"></a>
+<span class="sourceLineNo">1495</span>      boolean isFirst = true;<a name="line.1495"></a>
+<span class="sourceLineNo">1496</span>      for (BalancerRegionLoad rl : regionLoadList) {<a name="line.1496"></a>
+<span class="sourceLineNo">1497</span>        double current = getCostFromRl(rl);<a name="line.1497"></a>
+<span class="sourceLineNo">1498</span>        if (isFirst) {<a name="line.1498"></a>
+<span class="sourceLineNo">1499</span>          isFirst = false;<a name="line.1499"></a>
+<span class="sourceLineNo">1500</span>        } else {<a name="line.1500"></a>
+<span class="sourceLineNo">1501</span>          cost += current - previous;<a name="line.1501"></a>
+<span class="sourceLineNo">1502</span>        }<a name="line.1502"></a>
+<span class="sourceLineNo">1503</span>        previous = current;<a name="line.1503"></a>
+<span class="sourceLineNo">1504</span>      }<a name="line.1504"></a>
+<span class="sourceLineNo">1505</span>      return Math.max(0, cost / (regionLoadList.size() - 1));<a name="line.1505"></a>
+<span class="sourceLineNo">1506</span>    }<a name="line.1506"></a>
+<span class="sourceLineNo">1507</span>  }<a name="line.1507"></a>
+<span class="sourceLineNo">1508</span><a name="line.1508"></a>
+<span class="sourceLineNo">1509</span>  /**<a name="line.1509"></a>
+<span class="sourceLineNo">1510</span>   * Compute the cost of total number of read requests  The more unbalanced the higher the<a name="line.1510"></a>
+<span class="sourceLineNo">1511</span>   * computed cost will be.  This uses a rolling average of regionload.<a name="line.1511"></a>
+<span class="sourceLineNo">1512</span>   */<a name="line.1512"></a>
 <span class="sourceLineNo">1513</span><a name="line.1513"></a>
-<span class="sourceLineNo">1514</span>    private static final String READ_REQUEST_COST_KEY =<a name="line.1514"></a>
-<span class="sourceLineNo">1515</span>        "hbase.master.balancer.stochastic.readRequestCost";<a name="line.1515"></a>
-<span class="sourceLineNo">1516</span>    private static final float DEFAULT_READ_REQUEST_COST = 5;<a name="line.1516"></a>
-<span class="sourceLineNo">1517</span><a name="line.1517"></a>
-<span class="sourceLineNo">1518</span>    ReadRequestCostFunction(Configuration conf) {<a name="line.1518"></a>
-<span class="sourceLineNo">1519</span>      super(conf);<a name="line.1519"></a>
-<span class="sourceLineNo">1520</span>      this.setMultiplier(conf.getFloat(READ_REQUEST_COST_KEY, DEFAULT_READ_REQUEST_COST));<a name="line.1520"></a>
-<span class="sourceLineNo">1521</span>    }<a name="line.1521"></a>
-<span class="sourceLineNo">1522</span><a name="line.1522"></a>
-<span class="sourceLineNo">1523</span>    @Override<a name="line.1523"></a>
-<span class="sourceLineNo">1524</span>    protected double getCostFromRl(BalancerRegionLoad rl) {<a name="line.1524"></a>
-<span class="sourceLineNo">1525</span>      return rl.getReadRequestsCount();<a name="line.1525"></a>
-<span class="sourceLineNo">1526</span>    }<a name="line.1526"></a>
-<span class="sourceLineNo">1527</span>  }<a name="line.1527"></a>
-<span class="sourceLineNo">1528</span><a name="line.1528"></a>
-<span class="sourceLineNo">1529</span>  /**<a name="line.1529"></a>
-<span class="sourceLineNo">1530</span>   * Compute the cost of total number of coprocessor requests  The more unbalanced the higher the<a name="line.1530"></a>
-<span class="sourceLineNo">1531</span>   * computed cost will be.  This uses a rolling average of regionload.<a name="line.1531"></a>
-<span class="sourceLineNo">1532</span>   */<a name="line.1532"></a>
-<span class="sourceLineNo">1533</span><a name="line.1533"></a>
-<span class="sourceLineNo">1534</span>  static class CPRequestCostFunction extends CostFromRegionLoadAsRateFunction {<a name="line.1534"></a>
+<span class="sourceLineNo">1514</span>  static class ReadRequestCostFunction extends CostFromRegionLoadAsRateFunction {<a name="line.1514"></a>
+<span class="sourceLineNo">1515</span><a name="line.1515"></a>
+<span class="sourceLineNo">1516</span>    private static final String READ_REQUEST_COST_KEY =<a name="line.1516"></a>
+<span class="sourceLineNo">1517</span>        "hbase.master.balancer.stochastic.readRequestCost";<a name="line.1517"></a>
+<span class="sourceLineNo">1518</span>    private static final float DEFAULT_READ_REQUEST_COST = 5;<a name="line.1518"></a>
+<span class="sourceLineNo">1519</span><a name="line.1519"></a>
+<span class="sourceLineNo">1520</span>    ReadRequestCostFunction(Configuration conf) {<a name="line.1520"></a>
+<span class="sourceLineNo">1521</span>      super(conf);<a name="line.1521"></a>
+<span class="sourceLineNo">1522</span>      this.setMultiplier(conf.getFloat(READ_REQUEST_COST_KEY, DEFAULT_READ_REQUEST_COST));<a name="line.1522"></a>
+<span class="sourceLineNo">1523</span>    }<a name="line.1523"></a>
+<span class="sourceLineNo">1524</span><a name="line.1524"></a>
+<span class="sourceLineNo">1525</span>    @Override<a name="line.1525"></a>
+<span class="sourceLineNo">1526</span>    protected double getCostFromRl(BalancerRegionLoad rl) {<a name="line.1526"></a>
+<span class="sourceLineNo">1527</span>      return rl.getReadRequestsCount();<a name="line.1527"></a>
+<span class="sourceLineNo">1528</span>    }<a name="line.1528"></a>
+<span class="sourceLineNo">1529</span>  }<a name="line.1529"></a>
+<span class="sourceLineNo">1530</span><a name="line.1530"></a>
+<span class="sourceLineNo">1531</span>  /**<a name="line.1531"></a>
+<span class="sourceLineNo">1532</span>   * Compute the cost of total number of coprocessor requests  The more unbalanced the higher the<a name="line.1532"></a>
+<span class="sourceLineNo">1533</span>   * computed cost will be.  This uses a rolling average of regionload.<a name="line.1533"></a>
+<span class="sourceLineNo">1534</span>   */<a name="line.1534"></a>
 <span class="sourceLineNo">1535</span><a name="line.1535"></a>
-<span class="sourceLineNo">1536</span>    private static final String CP_REQUEST_COST_KEY =<a name="line.1536"></a>
-<span class="sourceLineNo">1537</span>        "hbase.master.balancer.stochastic.cpRequestCost";<a name="line.1537"></a>
-<span class="sourceLineNo">1538</span>    private static final float DEFAULT_CP_REQUEST_COST = 5;<a name="line.1538"></a>
-<span class="sourceLineNo">1539</span><a name="line.1539"></a>
-<span class="sourceLineNo">1540</span>    CPRequestCostFunction(Configuration conf) {<a name="line.1540"></a>
-<span class="sourceLineNo">1541</span>      super(conf);<a name="line.1541"></a>
-<span class="sourceLineNo">1542</span>      this.setMultiplier(conf.getFloat(CP_REQUEST_COST_KEY, DEFAULT_CP_REQUEST_COST));<a name="line.1542"></a>
-<span class="sourceLineNo">1543</span>    }<a name="line.1543"></a>
-<span class="sourceLineNo">1544</span><a name="line.1544"></a>
-<span class="sourceLineNo">1545</span>    @Override<a name="line.1545"></a>
-<span class="sourceLineNo">1546</span>    protected double getCostFromRl(BalancerRegionLoad rl) {<a name="line.1546"></a>
-<span class="sourceLineNo">1547</span>      return rl.getCpRequestsCount();<a name="line.1547"></a>
-<span class="sourceLineNo">1548</span>    }<a name="line.1548"></a>
-<span class="sourceLineNo">1549</span>  }<a name="line.1549"></a>
-<span class="sourceLineNo">1550</span><a name="line.1550"></a>
-<span class="sourceLineNo">1551</span>  /**<a name="line.1551"></a>
-<span class="sourceLineNo">1552</span>   * Compute the cost of total number of write requests.  The more unbalanced the higher the<a name="line.1552"></a>
-<span class="sourceLineNo">1553</span>   * computed cost will be.  This uses a rolling average of regionload.<a name="line.1553"></a>
-<span class="sourceLineNo">1554</span>   */<a name="line.1554"></a>
-<span class="sourceLineNo">1555</span>  static class WriteRequestCostFunction extends CostFromRegionLoadAsRateFunction {<a name="line.1555"></a>
-<span class="sourceLineNo">1556</span><a name="line.1556"></a>
-<span class="sourceLineNo">1557</span>    private static final String WRITE_REQUEST_COST_KEY =<a name="line.1557"></a>
-<span class="sourceLineNo">1558</span>        "hbase.master.balancer.stochastic.writeRequestCost";<a name="line.1558"></a>
-<span class="sourceLineNo">1559</span>    private static final float DEFAULT_WRITE_REQUEST_COST = 5;<a name="line.1559"></a>
-<span class="sourceLineNo">1560</span><a name="line.1560"></a>
-<span class="sourceLineNo">1561</span>    WriteRequestCostFunction(Configuration conf) {<a name="line.1561"></a>
-<span class="sourceLineNo">1562</span>      super(conf);<a name="line.1562"></a>
-<span class="sourceLineNo">1563</span>      this.setMultiplier(conf.getFloat(WRITE_REQUEST_COST_KEY, DEFAULT_WRITE_REQUEST_COST));<a name="line.1563"></a>
-<span class="sourceLineNo">1564</span>    }<a name="line.1564"></a>
-<span class="sourceLineNo">1565</span><a name="line.1565"></a>
-<span class="sourceLineNo">1566</span>    @Override<a name="line.1566"></a>
-<span class="sourceLineNo">1567</span>    protected double getCostFromRl(BalancerRegionLoad rl) {<a name="line.1567"></a>
-<span class="sourceLineNo">1568</span>      return rl.getWriteRequestsCount();<a name="line.1568"></a>
-<span class="sourceLineNo">1569</span>    }<a name="line.1569"></a>
-<span class="sourceLineNo">1570</span>  }<a name="line.1570"></a>
-<span class="sourceLineNo">1571</span><a name="line.1571"></a>
-<span class="sourceLineNo">1572</span>  /**<a name="line.1572"></a>
-<span class="sourceLineNo">1573</span>   * A cost function for region replicas. We give a very high cost to hosting<a name="line.1573"></a>
-<span class="sourceLineNo">1574</span>   * replicas of the same region in the same host. We do not prevent the case<a name="line.1574"></a>
-<span class="sourceLineNo">1575</span>   * though, since if numReplicas &gt; numRegionServers, we still want to keep the<a name="line.1575"></a>
-<span class="sourceLineNo">1576</span>   * replica open.<a name="line.1576"></a>
-<span class="sourceLineNo">1577</span>   */<a name="line.1577"></a>
-<span class="sourceLineNo">1578</span>  static class RegionReplicaHostCostFunction extends CostFunction {<a name="line.1578"></a>
-<span class="sourceLineNo">1579</span>    private static final String REGION_REPLICA_HOST_COST_KEY =<a name="line.1579"></a>
-<span class="sourceLineNo">1580</span>        "hbase.master.balancer.stochastic.regionReplicaHostCostKey";<a name="line.1580"></a>
-<span class="sourceLineNo">1581</span>    private static final float DEFAULT_REGION_REPLICA_HOST_COST_KEY = 100000;<a name="line.1581"></a>
-<span class="sourceLineNo">1582</span><a name="line.1582"></a>
-<span class="sourceLineNo">1583</span>    long maxCost = 0;<a name="line.1583"></a>
-<span class="sourceLineNo">1584</span>    long[] costsPerGroup; // group is either server, host or rack<a name="line.1584"></a>
-<span class="sourceLineNo">1585</span>    int[][] primariesOfRegionsPerGroup;<a name="line.1585"></a>
-<span class="sourceLineNo">1586</span><a name="line.1586"></a>
-<span class="sourceLineNo">1587</span>    public RegionReplicaHostCostFunction(Configuration conf) {<a name="line.1587"></a>
-<span class="sourceLineNo">1588</span>      super(conf);<a name="line.1588"></a>
-<span class="sourceLineNo">1589</span>      this.setMultiplier(conf.getFloat(REGION_REPLICA_HOST_COST_KEY,<a name="line.1589"></a>
-<span class="sourceLineNo">1590</span>        DEFAULT_REGION_REPLICA_HOST_COST_KEY));<a name="line.1590"></a>
-<span class="sourceLineNo">1591</span>    }<a name="line.1591"></a>
-<span class="sourceLineNo">1592</span><a name="line.1592"></a>
-<span class="sourceLineNo">1593</span>    @Override<a name="line.1593"></a>
-<span class="sourceLineNo">1594</span>    void init(Cluster cluster) {<a name="line.1594"></a>
-<span class="sourceLineNo">1595</span>      super.init(cluster);<a name="line.1595"></a>
-<span class="sourceLineNo">1596</span>      // max cost is the case where every region replica is hosted together regardless of host<a name="line.1596"></a>
-<span class="sourceLineNo">1597</span>      maxCost = cluster.numHosts &gt; 1 ? getMaxCost(cluster) : 0;<a name="line.1597"></a>
-<span class="sourceLineNo">1598</span>      costsPerGroup = new long[cluster.numHosts];<a name="line.1598"></a>
-<span class="sourceLineNo">1599</span>      primariesOfRegionsPerGroup = cluster.multiServersPerHost // either server based or host based<a name="line.1599"></a>
-<span class="sourceLineNo">1600</span>          ? cluster.primariesOfRegionsPerHost<a name="line.1600"></a>
-<span class="sourceLineNo">1601</span>          : cluster.primariesOfRegionsPerServer;<a name="line.1601"></a>
-<span class="sourceLineNo">1602</span>      for (int i = 0 ; i &lt; primariesOfRegionsPerGroup.length; i++) {<a name="line.1602"></a>
-<span class="sourceLineNo">1603</span>        costsPerGroup[i] = costPerGroup(primariesOfRegionsPerGroup[i]);<a name="line.1603"></a>
-<span class="sourceLineNo">1604</span>      }<a name="line.1604"></a>
-<span class="sourceLineNo">1605</span>    }<a name="line.1605"></a>
-<span class="sourceLineNo">1606</span><a name="line.1606"></a>
-<span class="sourceLineNo">1607</span>    long getMaxCost(Cluster cluster) {<a name="line.1607"></a>
-<span class="sourceLineNo">1608</span>      if (!cluster.hasRegionReplicas) {<a name="line.1608"></a>
-<span class="sourceLineNo">1609</span>        return 0; // short circuit<a name="line.1609"></a>
-<span class="sourceLineNo">1610</span>      }<a name="line.1610"></a>
-<span class="sourceLineNo">1611</span>      // max cost is the case where every region replica is hosted together regardless of host<a name="line.1611"></a>
-<span class="sourceLineNo">1612</span>      int[] primariesOfRegions = new int[cluster.numRegions];<a name="line.1612"></a>
-<span class="sourceLineNo">1613</span>      System.arraycopy(cluster.regionIndexToPrimaryIndex, 0, primariesOfRegions, 0,<a name="line.1613"></a>
-<span class="sourceLineNo">1614</span>          cluster.regions.length);<a name="line.1614"></a>
-<span class="sourceLineNo">1615</span><a name="line.1615"></a>
-<span class="sourceLineNo">1616</span>      Arrays.sort(primariesOfRegions);<a name="line.1616"></a>
+<span class="sourceLineNo">1536</span>  static class CPRequestCostFunction extends CostFromRegionLoadAsRateFunction {<a name="line.1536"></a>
+<span class="sourceLineNo">1537</span><a name="line.1537"></a>
+<span class="sourceLineNo">1538</span>    private static final String CP_REQUEST_COST_KEY =<a name="line.1538"></a>
+<span class="sourceLineNo">1539</span>        "hbase.master.balancer.stochastic.cpRequestCost";<a name="line.1539"></a>
+<span class="sourceLineNo">1540</span>    private static final float DEFAULT_CP_REQUEST_COST = 5;<a name="line.1540"></a>
+<span class="sourceLineNo">1541</span><a name="line.1541"></a>
+<span class="sourceLineNo">1542</span>    CPRequestCostFunction(Configuration conf) {<a name="line.1542"></a>
+<span class="sourceLineNo">1543</span>      super(conf);<a name="line.1543"></a>
+<span class="sourceLineNo">1544</span>      this.setMultiplier(conf.getFloat(CP_REQUEST_COST_KEY, DEFAULT_CP_REQUEST_COST));<a name="line.1544"></a>
+<span class="sourceLineNo">1545</span>    }<a name="line.1545"></a>
+<span class="sourceLineNo">1546</span><a name="line.1546"></a>
+<span class="sourceLineNo">1547</span>    @Override<a name="line.1547"></a>
+<span class="sourceLineNo">1548</span>    protected double getCostFromRl(BalancerRegionLoad rl) {<a name="line.1548"></a>
+<span class="sourceLineNo">1549</span>      return rl.getCpRequestsCount();<a name="line.1549"></a>
+<span class="sourceLineNo">1550</span>    }<a name="line.1550"></a>
+<span class="sourceLineNo">1551</span>  }<a name="line.1551"></a>
+<span class="sourceLineNo">1552</span><a name="line.1552"></a>
+<span class="sourceLineNo">1553</span>  /**<a name="line.1553"></a>
+<span class="sourceLineNo">1554</span>   * Compute the cost of total number of write requests.  The more unbalanced the higher the<a name="line.1554"></a>
+<span class="sourceLineNo">1555</span>   * computed cost will be.  This uses a rolling average of regionload.<a name="line.1555"></a>
+<span class="sourceLineNo">1556</span>   */<a name="line.1556"></a>
+<span class="sourceLineNo">1557</span>  static class WriteRequestCostFunction extends CostFromRegionLoadAsRateFunction {<a name="line.1557"></a>
+<span class="sourceLineNo">1558</span><a name="line.1558"></a>
+<span class="sourceLineNo">1559</span>    private static final String WRITE_REQUEST_COST_KEY =<a name="line.1559"></a>
+<span class="sourceLineNo">1560</span>        "hbase.master.balancer.stochastic.writeRequestCost";<a name="line.1560"></a>
+<span class="sourceLineNo">1561</span>    private static final float DEFAULT_WRITE_REQUEST_COST = 5;<a name="line.1561"></a>
+<span class="sourceLineNo">1562</span><a name="line.1562"></a>
+<span class="sourceLineNo">1563</span>    WriteRequestCostFunction(Configuration conf) {<a name="line.1563"></a>
+<span class="sourceLineNo">1564</span>      super(conf);<a name="line.1564"></a>
+<span class="sourceLineNo">1565</span>      this.setMultiplier(conf.getFloat(WRITE_REQUEST_COST_KEY, DEFAULT_WRITE_REQUEST_COST));<a name="line.1565"></a>
+<span class="sourceLineNo">1566</span>    }<a name="line.1566"></a>
+<span class="sourceLineNo">1567</span><a name="line.1567"></a>
+<span class="sourceLineNo">1568</span>    @Override<a name="line.1568"></a>
+<span class="sourceLineNo">1569</span>    protected double getCostFromRl(BalancerRegionLoad rl) {<a name="line.1569"></a>
+<span class="sourceLineNo">1570</span>      return rl.getWriteRequestsCount();<a name="line.1570"></a>
+<span class="sourceLineNo">1571</span>    }<a name="line.1571"></a>
+<span class="sourceLineNo">1572</span>  }<a name="line.1572"></a>
+<span class="sourceLineNo">1573</span><a name="line.1573"></a>
+<span class="sourceLineNo">1574</span>  /**<a name="line.1574"></a>
+<span class="sourceLineNo">1575</span>   * A cost function for region replicas. We give a very high cost to hosting<a name="line.1575"></a>
+<span class="sourceLineNo">1576</span>   * replicas of the same region in the same host. We do not prevent the case<a name="line.1576"></a>
+<span class="sourceLineNo">1577</span>   * though, since if numReplicas &gt; numRegionServers, we still want to keep the<a name="line.1577"></a>
+<span class="sourceLineNo">1578</span>   * replica open.<a name="line.1578"></a>
+<span class="sourceLineNo">1579</span>   */<a name="line.1579"></a>
+<span class="sourceLineNo">1580</span>  static class RegionReplicaHostCostFunction extends CostFunction {<a name="line.1580"></a>
+<span class="sourceLineNo">1581</span>    private static final String REGION_REPLICA_HOST_COST_KEY =<a name="line.1581"></a>
+<span class="sourceLineNo">1582</span>        "hbase.master.balancer.stochastic.regionReplicaHostCostKey";<a name="line.1582"></a>
+<span class="sourceLineNo">1583</span>    private static final float DEFAULT_REGION_REPLICA_HOST_COST_KEY = 100000;<a name="line.1583"></a>
+<span class="sourceLineNo">1584</span><a name="line.1584"></a>
+<span class="sourceLineNo">1585</span>    long maxCost = 0;<a name="line.1585"></a>
+<span class="sourceLineNo">1586</span>    long[] costsPerGroup; // group is either server, host or rack<a name="line.1586"></a>
+<span class="sourceLineNo">1587</span>    int[][] primariesOfRegionsPerGroup;<a name="line.1587"></a>
+<span class="sourceLineNo">1588</span><a name="line.1588"></a>
+<span class="sourceLineNo">1589</span>    public RegionReplicaHostCostFunction(Configuration conf) {<a name="line.1589"></a>
+<span class="sourceLineNo">1590</span>      super(conf);<a name="line.1590"></a>
+<span class="sourceLineNo">1591</span>      this.setMultiplier(conf.getFloat(REGION_REPLICA_HOST_COST_KEY,<a name="line.1591"></a>
+<span class="sourceLineNo">1592</span>        DEFAULT_REGION_REPLICA_HOST_COST_KEY));<a name="line.1592"></a>
+<span class="sourceLineNo">1593</span>    }<a name="line.1593"></a>
+<span class="sourceLineNo">1594</span><a name="line.1594"></a>
+<span class="sourceLineNo">1595</span>    @Override<a name="line.1595"></a>
+<span class="sourceLineNo">1596</span>    void init(Cluster cluster) {<a name="line.1596"></a>
+<span class="sourceLineNo">1597</span>      super.init(cluster);<a name="line.1597"></a>
+<span class="sourceLineNo">1598</span>      // max cost is the case where every region replica is hosted together regardless of host<a name="line.1598"></a>
+<span class="sourceLineNo">1599</span>      maxCost = cluster.numHosts &gt; 1 ? getMaxCost(cluster) : 0;<a name="line.1599"></a>
+<span class="sourceLineNo">1600</span>      costsPerGroup = new long[cluster.numHosts];<a name="line.1600"></a>
+<span class="sourceLineNo">1601</span>      primariesOfRegionsPerGroup = cluster.multiServersPerHost // either server based or host based<a name="line.1601"></a>
+<span class="sourceLineNo">1602</span>          ? cluster.primariesOfRegionsPerHost<a name="line.1602"></a>
+<span class="sourceLineNo">1603</span>          : cluster.primariesOfRegionsPerServer;<a name="line.1603"></a>
+<span class="sourceLineNo">1604</span>      for (int i = 0 ; i &lt; primariesOfRegionsPerGroup.length; i++) {<a name="line.1604"></a>
+<span class="sourceLineNo">1605</span>        costsPerGroup[i] = costPerGroup(primariesOfRegionsPerGroup[i]);<a name="line.1605"></a>
+<span class="sourceLineNo">1606</span>      }<a name="line.1606"></a>
+<span class="sourceLineNo">1607</span>    }<a name="line.1607"></a>
+<span class="sourceLineNo">1608</span><a name="line.1608"></a>
+<span class="sourceLineNo">1609</span>    long getMaxCost(Cluster cluster) {<a name="line.1609"></a>
+<span class="sourceLineNo">1610</span>      if (!cluster.hasRegionReplicas) {<a name="line.1610"></a>
+<span class="sourceLineNo">1611</span>        return 0; // short circuit<a name="line.1611"></a>
+<span class="sourceLineNo">1612</span>      }<a name="line.1612"></a>
+<span class="sourceLineNo">1613</span>      // max cost is the case where every region replica is hosted together regardless of host<a name="line.1613"></a>
+<span class="sourceLineNo">1614</span>      int[] primariesOfRegions = new int[cluster.numRegions];<a name="line.1614"></a>
+<span class="sourceLineNo">1615</span>      System.arraycopy(cluster.regionIndexToPrimaryIndex, 0, primariesOfRegions, 0,<a name="line.1615"></a>
+<span class="sourceLineNo">1616</span>          cluster.regions.length);<a name="line.1616"></a>
 <span class="sourceLineNo">1617</span><a name="line.1617"></a>
-<span class="sourceLineNo">1618</span>      // compute numReplicas from the sorted array<a name="line.1618"></a>
-<span class="sourceLineNo">1619</span>      return costPerGroup(primariesOfRegions);<a name="line.1619"></a>
-<span class="sourceLineNo">1620</span>    }<a name="line.1620"></a>
-<span class="sourceLineNo">1621</span><a name="line.1621"></a>
-<span class="sourceLineNo">1622</span>    @Override<a name="line.1622"></a>
-<span class="sourceLineNo">1623</span>    boolean isNeeded() {<a name="line.1623"></a>
-<span class="sourceLineNo">1624</span>      return cluster.hasRegionReplicas;<a name="line.1624"></a>
-<span class="sourceLineNo">1625</span>    }<a name="line.1625"></a>
-<span class="sourceLineNo">1626</span><a name="line.1626"></a>
-<span class="sourceLineNo">1627</span>    @Override<a name="line.1627"></a>
-<span class="sourceLineNo">1628</span>    protected double cost() {<a name="line.1628"></a>
-<span class="sourceLineNo">1629</span>      if (maxCost &lt;= 0) {<a name="line.1629"></a>
-<span class="sourceLineNo">1630</span>        return 0;<a name="line.1630"></a>
-<span class="sourceLineNo">1631</span>      }<a name="line.1631"></a>
-<span class="sourceLineNo">1632</span><a name="line.1632"></a>
-<span class="sourceLineNo">1633</span>      long totalCost = 0;<a name="line.1633"></a>
-<span class="sourceLineNo">1634</span>      for (int i = 0 ; i &lt; costsPerGroup.length; i++) {<a name="line.1634"></a>
-<span class="sourceLineNo">1635</span>        totalCost += costsPerGroup[i];<a name="line.1635"></a>
-<span class="sourceLineNo">1636</span>      }<a name="line.1636"></a>
-<span class="sourceLineNo">1637</span>      return scale(0, maxCost, totalCost);<a name="line.1637"></a>
-<span class="sourceLineNo">1638</span>    }<a name="line.1638"></a>
-<span class="sourceLineNo">1639</span><a name="line.1639"></a>
-<span class="sourceLineNo">1640</span>    /**<a name="line.1640"></a>
-<span class="sourceLineNo">1641</span>     * For each primary region, it computes the total number of replicas in the array (numReplicas)<a name="line.1641"></a>
-<span class="sourceLineNo">1642</span>     * and returns a sum of numReplicas-1 squared. For example, if the server hosts<a name="line.1642"></a>
-<span class="sourceLineNo">1643</span>     * regions a, b, c, d, e, f where a and b are same replicas, and c,d,e are same replicas, it<a name="line.1643"></a>
-<span class="sourceLineNo">1644</span>     * returns (2-1) * (2-1) + (3-1) * (3-1) + (1-1) * (1-1).<a name="line.1644"></a>
-<span class="sourceLineNo">1645</span>     * @param primariesOfRegions a sorted array of primary regions ids for the regions hosted<a name="line.1645"></a>
-<span class="sourceLineNo">1646</span>     * @return a sum of numReplicas-1 squared for each primary region in the group.<a name="line.1646"></a>
-<span class="sourceLineNo">1647</span>     */<a name="line.1647"></a>
-<span class="sourceLineNo">1648</span>    protected long costPerGroup(int[] primariesOfRegions) {<a name="line.1648"></a>
-<span class="sourceLineNo">1649</span>      long cost = 0;<a name="line.1649"></a>
-<span class="sourceLineNo">1650</span>      int currentPrimary = -1;<a name="line.1650"></a>
-<span class="sourceLineNo">1651</span>      int currentPrimaryIndex = -1;<a name="line.1651"></a>
-<span class="sourceLineNo">1652</span>      // primariesOfRegions is a sorted array of primary ids of regions. Replicas of regions<a name="line.1652"></a>
-<span class="sourceLineNo">1653</span>      // sharing the same primary will have consecutive numbers in the array.<a name="line.1653"></a>
-<span class="sourceLineNo">1654</span>      for (int j = 0 ; j &lt;= primariesOfRegions.length; j++) {<a name="line.1654"></a>
-<span class="sourceLineNo">1655</span>        int primary = j &lt; primariesOfRegions.length ? primariesOfRegions[j] : -1;<a name="line.1655"></a>
-<span class="sourceLineNo">1656</span>        if (primary != currentPrimary) { // we see a new primary<a name="line.1656"></a>
-<span class="sourceLineNo">1657</span>          int numReplicas = j - currentPrimaryIndex;<a name="line.1657"></a>
-<span class="sourceLineNo">1658</span>          // square the cost<a name="line.1658"></a>
-<span class="sourceLineNo">1659</span>          if (numReplicas &gt; 1) { // means consecutive primaries, indicating co-location<a name="line.1659"></a>
-<span class="sourceLineNo">1660</span>            cost += (numReplicas - 1) * (numReplicas - 1);<a name="line.1660"></a>
-<span class="sourceLineNo">1661</span>          }<a name="line.1661"></a>
-<span class="sourceLineNo">1662</span>          currentPrimary = primary;<a name="line.1662"></a>
-<span class="sourceLineNo">1663</span>          currentPrimaryIndex = j;<a name="line.1663"></a>
-<span class="sourceLineNo">1664</span>        }<a name="line.1664"></a>
-<span class="sourceLineNo">1665</span>      }<a name="line.1665"></a>
-<span class="sourceLineNo">1666</span><a name="line.1666"></a>
-<span class="sourceLineNo">1667</span>      return cost;<a name="line.1667"></a>
-<span class="sourceLineNo">1668</span>    }<a name="line.1668"></a>
-<span class="sourceLineNo">1669</span><a name="line.1669"></a>
-<span class="sourceLineNo">1670</span>    @Override<a name="line.1670"></a>
-<span class="sourceLineNo">1671</span>    protected void regionMoved(int region, int oldServer, int newServer) {<a name="line.1671"></a>
-<span class="sourceLineNo">1672</span>      if (maxCost &lt;= 0) {<a name="line.1672"></a>
-<span class="sourceLineNo">1673</span>        return; // no need to compute<a name="line.1673"></a>
-<span class="sourceLineNo">1674</span>      }<a name="line.1674"></a>
-<span class="sourceLineNo">1675</span>      if (cluster.multiServersPerHost) {<a name="line.1675"></a>
-<span class="sourceLineNo">1676</span>        int oldHost = cluster.serverIndexToHostIndex[oldServer];<a name="line.1676"></a>
-<span class="sourceLineNo">1677</span>        int newHost = cluster.serverIndexToHostIndex[newServer];<a name="line.1677"></a>
-<span class="sourceLineNo">1678</span>        if (newHost != oldHost) {<a name="line.1678"></a>
-<span class="sourceLineNo">1679</span>          costsPerGroup[oldHost] = costPerGroup(cluster.primariesOfRegionsPerHost[oldHost]);<a name="line.1679"></a>
-<span class="sourceLineNo">1680</span>          costsPerGroup[newHost] = costPerGroup(cluster.primariesOfRegionsPerHost[newHost]);<a name="line.1680"></a>
-<span class="sourceLineNo">1681</span>        }<a name="line.1681"></a>
-<span class="sourceLineNo">1682</span>      } else {<a name="line.1682"></a>
-<span class="sourceLineNo">1683</span>        costsPerGroup[oldServer] = costPerGroup(cluster.primariesOfRegionsPerServer[oldServer]);<a name="line.1683"></a>
-<span class="sourceLineNo">1684</span>        costsPerGroup[newServer] = costPerGroup(cluster.primariesOfRegionsPerServer[newServer]);<a name="line.1684"></a>
-<span class="sourceLineNo">1685</span>      }<a name="line.1685"></a>
-<span class="sourceLineNo">1686</span>    }<a name="line.1686"></a>
-<span class="sourceLineNo">1687</span>  }<a name="line.1687"></a>
-<span class="sourceLineNo">1688</span><a name="line.1688"></a>
-<span class="sourceLineNo">1689</span>  /**<a name="line.1689"></a>
-<span class="sourceLineNo">1690</span>   * A cost function for region replicas for the rack distribution. We give a relatively high<a name="line.1690"></a>
-<span class="sourceLineNo">1691</span>   * cost to hosting replicas of the same region in the same rack. We do not prevent the case<a name="line.1691"></a>
-<span class="sourceLineNo">1692</span>   * though.<a name="line.1692"></a>
-<span class="sourceLineNo">1693</span>   */<a name="line.1693"></a>
-<span class="sourceLineNo">1694</span>  static class RegionReplicaRackCostFunction extends RegionReplicaHostCostFunction {<a name="line.1694"></a>
-<span class="sourceLineNo">1695</span>    private static final String REGION_REPLICA_RACK_COST_KEY =<a name="line.1695"></a>
-<span class="sourceLineNo">1696</span>        "hbase.master.balancer.stochastic.regionReplicaRackCostKey";<a name="line.1696"></a>
-<span class="sourceLineNo">1697</span>    private static final float DEFAULT_REGION_REPLICA_RACK_COST_KEY = 10000;<a name="line.1697"></a>
-<span class="sourceLineNo">1698</span><a name="line.1698"></a>
-<span class="sourceLineNo">1699</span>    public RegionReplicaRackCostFunction(Configuration conf) {<a name="line.1699"></a>
-<span class="sourceLineNo">1700</span>      super(conf);<a name="line.1700"></a>
-<span class="sourceLineNo">1701</span>      this.setMultiplier(conf.getFloat(REGION_REPLICA_RACK_COST_KEY,<a name="line.1701"></a>
-<span class="sourceLineNo">1702</span>        DEFAULT_REGION_REPLICA_RACK_COST_KEY));<a name="line.1702"></a>
-<span class="sourceLineNo">1703</span>    }<a name="line.1703"></a>
-<span class="sourceLineNo">1704</span><a name="line.1704"></a>
-<span class="sourceLineNo">1705</span>    @Override<a name="line.1705"></a>
-<span class="sourceLineNo">1706</span>    void init(Cluster cluster) {<a name="line.1706"></a>
-<span class="sourceLineNo">1707</span>      this.cluster = cluster;<a name="line.1707"></a>
-<span class="sourceLineNo">1708</span>      if (cluster.numRacks &lt;= 1) {<a name="line.1708"></a>
-<span class="sourceLineNo">1709</span>        maxCost = 0;<a name="line.1709"></a>
-<span class="sourceLineNo">1710</span>        return; // disabled for 1 rack<a name="line.1710"></a>
-<span class="sourceLineNo">1711</span>      }<a name="line.1711"></a>
-<span class="sourceLineNo">1712</span>      // max cost is the case where every region replica is hosted together regardless of rack<a name="line.1712"></a>
-<span class="sourceLineNo">1713</span>      maxCost = getMaxCost(cluster);<a name="line.1713"></a>
-<span class="sourceLineNo">1714</span>      costsPerGroup = new long[cluster.numRacks];<a name="line.1714"></a>
-<span class="sourceLineNo">1715</span>      for (int i = 0 ; i &lt; cluster.primariesOfRegionsPerRack.length; i++) {<a name="line.1715"></a>
-<span class="sourceLineNo">1716</span>        costsPerGroup[i] = costPerGroup(cluster.primariesOfRegionsPerRack[i]);<a name="line.1716"></a>
-<span class="sourceLineNo">1717</span>      }<a name="line.1717"></a>
-<span class="sourceLineNo">1718</span>    }<a name="line.1718"></a>
-<span class="sourceLineNo">1719</span><a name="line.1719"></a>
-<span class="sourceLineNo">1720</span>    @Override<a name="line.1720"></a>
-<span class="sourceLineNo">1721</span>    protected void regionMoved(int region, int oldServer, int newServer) {<a name="line.1721"></a>
-<span class="sourceLineNo">1722</span>      if (maxCost &lt;= 0) {<a name="line.1722"></a>
-<span class="sourceLineNo">1723</span>        return; // no need to compute<a name="line.1723"></a>
-<span class="sourceLineNo">1724</span>      }<a name="line.1724"></a>
-<span class="sourceLineNo">1725</span>      int oldRack = cluster.serverIndexToRackIndex[oldServer];<a name="line.1725"></a>
-<span class="sourceLineNo">1726</span>      int newRack = cluster.serverIndexToRackIndex[newServer];<a name="line.1726"></a>
-<span class="sourceLineNo">1727</span>      if (newRack != oldRack) {<a name="line.1727"></a>
-<span class="sourceLineNo">1728</span>        costsPerGroup[oldRack] = costPerGroup(cluster.primariesOfRegionsPerRack[oldRack]);<a name="line.1728"></a>
-<span class="sourceLineNo">1729</span>        costsPerGroup[newRack] = costPerGroup(cluster.primariesOfRegionsPerRack[newRack]);<a name="line.1729"></a>
-<span class="sourceLineNo">1730</span>      }<a name="line.1730"></a>
-<span class="sourceLineNo">1731</span>    }<a name="line.1731"></a>
-<span class="sourceLineNo">1732</span>  }<a name="line.1732"></a>
-<span class="sourceLineNo">1733</span><a name="line.1733"></a>
-<span class="sourceLineNo">1734</span>  /**<a name="line.1734"></a>
-<span class="sourceLineNo">1735</span>   * Compute the cost of total memstore size.  The more unbalanced the higher the<a name="line.1735"></a>
-<span class="sourceLineNo">1736</span>   * computed cost will be.  This uses a rolling average of regionload.<a name="line.1736"></a>
-<span class="sourceLineNo">1737</span>   */<a name="line.1737"></a>
-<span class="sourceLineNo">1738</span>  static class MemStoreSizeCostFunction extends CostFromRegionLoadAsRateFunction {<a name="line.1738"></a>
-<span class="sourceLineNo">1739</span><a name="line.1739"></a>
-<span class="sourceLineNo">1740</span>    private static final String MEMSTORE_SIZE_COST_KEY =<a name="line.1740"></a>
-<span class="sourceLineNo">1741</span>        "hbase.master.balancer.stochastic.memstoreSizeCost";<a name="line.1741"></a>
-<span class="sourceLineNo">1742</span>    private static final float DEFAULT_MEMSTORE_SIZE_COST = 5;<a name="line.1742"></a>
-<span class="sourceLineNo">1743</span><a name="line.1743"></a>
-<span class="sourceLineNo">1744</span>    MemStoreSizeCostFunction(Configuration conf) {<a name="line.1744"></a>
-<span class="sourceLineNo">1745</span>      super(conf);<a name="line.1745"></a>
-<span class="sourceLineNo">1746</span>      this.setMultiplier(conf.getFloat(MEMSTORE_SIZE_COST_KEY, DEFAULT_MEMSTORE_SIZE_COST));<a name="line.1746"></a>
-<span class="sourceLineNo">1747</span>    }<a name="line.1747"></a>
-<span class="sourceLineNo">1748</span><a name="line.1748"></a>
-<span class="sourceLineNo">1749</span>    @Override<a name="line.1749"></a>
-<span class="sourceLineNo">1750</span>    protected double getCostFromRl(BalancerRegionLoad rl) {<a name="line.1750"></a>
-<span class="sourceLineNo">1751</span>      return rl.getMemStoreSizeMB();<a name="line.1751"></a>
-<span class="sourceLineNo">1752</span>    }<a name="line.1752"></a>
-<span class="sourceLineNo">1753</span>  }<a name="line.1753"></a>
-<span class="sourceLineNo">1754</span><a name="line.1754"></a>
-<span class="sourceLineNo">1755</span>  /**<a name="line.1755"></a>
-<span class="sourceLineNo">1756</span>   * Compute the cost of total open storefiles size.  The more unbalanced the higher the<a name="line.1756"></a>
-<span class="sourceLineNo">1757</span>   * computed cost will be.  This uses a rolling average of regionload.<a name="line.1757"></a>
-<span class="sourceLineNo">1758</span>   */<a name="line.1758"></a>
-<span class="sourceLineNo">1759</span>  static class StoreFileCostFunction extends CostFromRegionLoadFunction {<a name="line.1759"></a>
-<span class="sourceLineNo">1760</span><a name="line.1760"></a>
-<span class="sourceLineNo">1761</span>    private static final String STOREFILE_SIZE_COST_KEY =<a name="line.1761"></a>
-<span class="sourceLineNo">1762</span>        "hbase.master.balancer.stochastic.storefileSizeCost";<a name="line.1762"></a>
-<span class="sourceLineNo">1763</span>    private static final float DEFAULT_STOREFILE_SIZE_COST = 5;<a name="line.1763"></a>
-<span class="sourceLineNo">1764</span><a name="line.1764"></a>
-<span class="sourceLineNo">1765</span>    StoreFileCostFunction(Configuration conf) {<a name="line.1765"></a>
-<span class="sourceLineNo">1766</span>      super(conf);<a name="line.1766"></a>
-<span class="sourceLineNo">1767</span>      this.setMultiplier(conf.getFloat(STOREFILE_SIZE_COST_KEY, DEFAULT_STOREFILE_SIZE_COST));<a name="line.1767"></a>
-<span class="sourceLineNo">1768</span>    }<a name="line.1768"></a>
-<span class="sourceLineNo">1769</span><a name="line.1769"></a>
-<span class="sourceLineNo">1770</span>    @Override<a name="line.1770"></a>
-<span class="sourceLineNo">1771</span>    protected double getCostFromRl(BalancerRegionLoad rl) {<a name="line.1771"></a>
-<span class="sourceLineNo">1772</span>      return rl.getStorefileSizeMB();<a name="line.1772"></a>
-<span class="sourceLineNo">1773</span>    }<a name="line.1773"></a>
-<span class="sourceLineNo">1774</span>  }<a name="line.1774"></a>
-<span class="sourceLineNo">1775</span><a name="line.1775"></a>
-<span class="sourceLineNo">1776</span>  /**<a name="line.1776"></a>
-<span class="sourceLineNo">1777</span>   * A helper function to compose the attribute name from tablename and costfunction name<a name="line.1777"></a>
-<span class="sourceLineNo">1778</span>   */<a name="line.1778"></a>
-<span class="sourceLineNo">1779</span>  public static String composeAttributeName(String tableName, String costFunctionName) {<a name="line.1779"></a>
-<span class="sourceLineNo">1780</span>    return tableName + TABLE_FUNCTION_SEP + costFunctionName;<a name="line.1780"></a>
-<span class="sourceLineNo">1781</span>  }<a name="line.1781"></a>
-<span class="sourceLineNo">1782</span>}<a name="line.1782"></a>
+<span class="sourceLineNo">1618</span>      Arrays.sort(primariesOfRegions);<a name="line.1618"></a>
+<span class="sourceLineNo">1619</span><a name="line.1619"></a>
+<span class="sourceLineNo">1620</span>      // compute numReplicas from the sorted array<a name="line.1620"></a>
+<span class="sourceLineNo">1621</span>      return costPerGroup(primariesOfRegions);<a name="line.1621"></a>
+<span class="sourceLineNo">1622</span>    }<a name="line.1622"></a>
+<span class="sourceLineNo">1623</span><a name="line.1623"></a>
+<span class="sourceLineNo">1624</span>    @Override<a name="line.1624"></a>
+<span class="sourceLineNo">1625</span>    boolean isNeeded() {<a name="line.1625"></a>
+<span class="sourceLineNo">1626</span>      return cluster.hasRegionReplicas;<a name="line.1626"></a>
+<span class="sourceLineNo">1627</span>    }<a name="line.1627"></a>
+<span class="sourceLineNo">1628</span><a name="line.1628"></a>
+<span class="sourceLineNo">1629</span>    @Override<a name="line.1629"></a>
+<span class="sourceLineNo">1630</span>    protected double cost() {<a name="line.1630"></a>
+<span class="sourceLineNo">1631</span>      if (maxCost &lt;= 0) {<a name="line.1631"></a>
+<span class="sourceLineNo">1632</span>        return 0;<a name="line.1632"></a>
+<span class="sourceLineNo">1633</span>      }<a name="line.1633"></a>
+<span class="sourceLineNo">1634</span><a name="line.1634"></a>
+<span class="sourceLineNo">1635</span>      long totalCost = 0;<a name="line.1635"></a>
+<span class="sourceLineNo">1636</span>      for (int i = 0 ; i &lt; costsPerGroup.length; i++) {<a name="line.1636"></a>
+<span class="sourceLineNo">1637</span>        totalCost += costsPerGroup[i];<a name="line.1637"></a>
+<span class="sourceLineNo">1638</span>      }<a name="line.1638"></a>
+<span class="sourceLineNo">1639</span>      return scale(0, maxCost, totalCost);<a name="line.1639"></a>
+<span class="sourceLineNo">1640</span>    }<a name="line.1640"></a>
+<span class="sourceLineNo">1641</span><a name="line.1641"></a>
+<span class="sourceLineNo">1642</span>    /**<a name="line.1642"></a>
+<span class="sourceLineNo">1643</span>     * For each primary region, it computes the total number of replicas in the array (numReplicas)<a name="line.1643"></a>
+<span class="sourceLineNo">1644</span>     * and returns a sum of numReplicas-1 squared. For example, if the server hosts<a name="line.1644"></a>
+<span class="sourceLineNo">1645</span>     * regions a, b, c, d, e, f where a and b are same replicas, and c,d,e are same replicas, it<a name="line.1645"></a>
+<span class="sourceLineNo">1646</span>     * returns (2-1) * (2-1) + (3-1) * (3-1) + (1-1) * (1-1).<a name="line.1646"></a>
+<span class="sourceLineNo">1647</span>     * @param primariesOfRegions a sorted array of primary regions ids for the regions hosted<a name="line.1647"></a>
+<span class="sourceLineNo">1648</span>     * @return a sum of numReplicas-1 squared for each primary region in the group.<a name="line.1648"></a>
+<span class="sourceLineNo">1649</span>     */<a name="line.1649"></a>
+<span class="sourceLineNo">1650</span>    protected long costPerGroup(int[] primariesOfRegions) {<a name="line.1650"></a>
+<span class="sourceLineNo">1651</span>      long cost = 0;<a name="line.1651"></a>
+<span class="sourceLineNo">1652</span>      int currentPrimary = -1;<a name="line.1652"></a>
+<span class="sourceLineNo">1653</span>      int currentPrimaryIndex = -1;<a name="line.1653"></a>
+<span class="sourceLineNo">1654</span>      // primariesOfRegions is a sorted array of primary ids of regions. Replicas of regions<a name="line.1654"></a>
+<span class="sourceLineNo">1655</span>      // sharing the same primary will have consecutive numbers in the array.<a name="line.1655"></a>
+<span class="sourceLineNo">1656</span>      for (int j = 0 ; j &lt;= primariesOfRegions.length; j++) {<a name="line.1656"></a>
+<span class="sourceLineNo">1657</span>        int primary = j &lt; primariesOfRegions.length ? primariesOfRegions[j] : -1;<a name="line.1657"></a>
+<span class="sourceLineNo">1658</span>        if (primary != currentPrimary) { // we see a new primary<a name="line.1658"></a>
+<span class="sourceLineNo">1659</span>          int numReplicas = j - currentPrimaryIndex;<a name="line.1659"></a>
+<span class="sourceLineNo">1660</span>          // square the cost<a name="line.1660"></a>
+<span class="sourceLineNo">1661</span>          if (numReplicas &gt; 1) { // means consecutive primaries, indicating co-location<a name="line.1661"></a>
+<span class="sourceLineNo">1662</span>            cost += (numReplicas - 1) * (numReplicas - 1);<a name="line.1662"></a>
+<span class="sourceLineNo">1663</span>          }<a name="line.1663"></a>
+<span class="sourceLineNo">1664</span>          currentPrimary = primary;<a name="line.1664"></a>
+<span class="sourceLineNo">1665</span>          currentPrimaryIndex = j;<a name="line.1665"></a>
+<span class="sourceLineNo">1666</span>        }<a name="line.1666"></a>
+<span class="sourceLineNo">1667</span>      }<a name="line.1667"></a>
+<span class="sourceLineNo">1668</span><a name="line.1668"></a>
+<span class="sourceLineNo">1669</span>      return cost;<a name="line.1669"></a>
+<span class="sourceLineNo">1670</span>    }<a name="line.1670"></a>
+<span class="sourceLineNo">1671</span><a name="line.1671"></a>
+<span class="sourceLineNo">1672</span>    @Override<a name="line.1672"></a>
+<span class="sourceLineNo">1673</span>    protected void regionMoved(int region, int oldServer, int newServer) {<a name="line.1673"></a>
+<span class="sourceLineNo">1674</span>      if (maxCost &lt;= 0) {<a name="line.1674"></a>
+<span class="sourceLineNo">1675</span>        return; // no need to compute<a name="line.1675"></a>
+<span class="sourceLineNo">1676</span>      }<a name="line.1676"></a>
+<span class="sourceLineNo">1677</span>      if (cluster.multiServersPerHost) {<a name="line.1677"></a>
+<span class="sourceLineNo">1678</span>        int oldHost = cluster.serverIndexToHostIndex[oldServer];<a name="line.1678"></a>
+<span class="sourceLineNo">1679</span>        int newHost = cluster.serverIndexToHostIndex[newServer];<a name="line.1679"></a>
+<span class="sourceLineNo">1680</span>        if (newHost != oldHost) {<a name="line.1680"></a>
+<span class="sourceLineNo">1681</span>          costsPerGroup[oldHost] = costPerGroup(cluster.primariesOfRegionsPerHost[oldHost]);<a name="line.1681"></a>
+<span class="sourceLineNo">1682</span>          costsPerGroup[newHost] = costPerGroup(cluster.primariesOfRegionsPerHost[newHost]);<a name="line.1682"></a>
+<span class="sourceLineNo">1683</span>        }<a name="line.1683"></a>
+<span class="sourceLineNo">1684</span>      } else {<a name="line.1684"></a>
+<span class="sourceLineNo">1685</span>        costsPerGroup[oldServer] = costPerGroup(cluster.primariesOfRegionsPerServer[oldServer]);<a name="line.1685"></a>
+<span class="sourceLineNo">1686</span>        costsPerGroup[newServer] = costPerGroup(cluster.primariesOfRegionsPerServer[newServer]);<a name="line.1686"></a>
+<span class="sourceLineNo">1687</span>      }<a name="line.1687"></a>
+<span class="sourceLineNo">1688</span>    }<a name="line.1688"></a>
+<span class="sourceLineNo">1689</span>  }<a name="line.1689"></a>
+<span class="sourceLineNo">1690</span><a name="line.1690"></a>
+<span class="sourceLineNo">1691</span>  /**<a name="line.1691"></a>
+<span class="sourceLineNo">1692</span>   * A cost function for region replicas for the rack distribution. We give a relatively high<a name="line.1692"></a>
+<span class="sourceLineNo">1693</span>   * cost to hosting replicas of the same region in the same rack. We do not prevent the case<a name="line.1693"></a>
+<span class="sourceLineNo">1694</span>   * though.<a name="line.1694"></a>
+<span class="sourceLineNo">1695</span>   */<a name="line.1695"></a>
+<span class="sourceLineNo">1696</span>  static class RegionReplicaRackCostFunction extends RegionReplicaHostCostFunction {<a name="line.1696"></a>
+<span class="sourceLineNo">1697</span>    private static final String REGION_REPLICA_RACK_COST_KEY =<a name="line.1697"></a>
+<span class="sourceLineNo">1698</span>        "hbase.master.balancer.stochastic.regionReplicaRackCostKey";<a name="line.1698"></a>
+<span class="sourceLineNo">1699</span>    private static final float DEFAULT_REGION_REPLICA_RACK_COST_KEY = 10000;<a name="line.1699"></a>
+<span class="sourceLineNo">1700</span><a name="line.1700"></a>
+<span class="sourceLineNo">1701</span>    public RegionReplicaRackCostFunction(Configuration conf) {<a name="line.1701"></a>
+<span class="sourceLineNo">1702</span>      super(conf);<a name="line.1702"></a>
+<span class="sourceLineNo">1703</span>      this.setMultiplier(conf.getFloat(REGION_REPLICA_RACK_COST_KEY,<a name="line.1703"></a>
+<span class="sourceLineNo">1704</span>        DEFAULT_REGION_REPLICA_RACK_COST_KEY));<a name="line.1704"></a>
+<span class="sourceLineNo">1705</span>    }<a name="line.1705"></a>
+<span class="sourceLineNo">1706</span><a name="line.1706"></a>
+<span class="sourceLineNo">1707</span>    @Override<a name="line.1707"></a>
+<span class="sourceLineNo">1708</span>    void init(Cluster cluster) {<a name="line.1708"></a>
+<span class="sourceLineNo">1709</span>      this.cluster = cluster;<a name="line.1709"></a>
+<span class="sourceLineNo">1710</span>      if (cluster.numRacks &lt;= 1) {<a name="line.1710"></a>
+<span class="sourceLineNo">1711</span>        maxCost = 0;<a name="line.1711"></a>
+<span class="sourceLineNo">1712</span>        return; // disabled for 1 rack<a name="line.1712"></a>
+<span class="sourceLineNo">1713</span>      }<a name="line.1713"></a>
+<span class="sourceLineNo">1714</span>      // max cost is the case where every region replica is hosted together regardless of rack<a name="line.1714"></a>
+<span class="sourceLineNo">1715</span>      maxCost = getMaxCost(cluster);<a name="line.1715"></a>
+<span class="sourceLineNo">1716</span>      costsPerGroup = new long[cluster.numRacks];<a name="line.1716"></a>
+<span class="sourceLineNo">1717</span>      for (int i = 0 ; i &lt; cluster.primariesOfRegionsPerRack.length; i++) {<a name="line.1717"></a>
+<span class="sourceLineNo">1718</span>        costsPerGroup[i] = costPerGroup(cluster.primariesOfRegionsPerRack[i]);<a name="line.1718"></a>
+<span class="sourceLineNo">1719</span>      }<a name="line.1719"></a>
+<span class="sourceLineNo">1720</span>    }<a name="line.1720"></a>
+<span class="sourceLineNo">1721</span><a name="line.1721"></a>
+<span class="sourceLineNo">1722</span>    @Override<a name="line.1722"></a>
+<span class="sourceLineNo">1723</span>    protected void regionMoved(int region, int oldServer, int newServer) {<a name="line.1723"></a>
+<span class="sourceLineNo">1724</span>      if (maxCost &lt;= 0) {<a name="line.1724"></a>
+<span class="sourceLineNo">1725</span>        return; // no need to compute<a name="line.1725"></a>
+<span class="sourceLineNo">1726</span>      }<a name="line.1726"></a>
+<span class="sourceLineNo">1727</span>      int oldRack = cluster.serverIndexToRackIndex[oldServer];<a name="line.1727"></a>
+<span class="sourceLineNo">1728</span>      int newRack = cluster.serverIndexToRackIndex[newServer];<a name="line.1728"></a>
+<span class="sourceLineNo">1729</span>      if (newRack != oldRack) {<a name="line.1729"></a>
+<span class="sourceLineNo">1730</span>        costsPerGroup[oldRack] = costPerGroup(cluster.primariesOfRegionsPerRack[oldRack]);<a name="line.1730"></a>
+<span class="sourceLineNo">1731</span>        costsPerGroup[newRack] = costPerGroup(cluster.primariesOfRegionsPerRack[newRack]);<a name="line.1731"></a>
+<span class="sourceLineNo">1732</span>      }<a name="line.1732"></a>
+<span class="sourceLineNo">1733</span>    }<a name="line.1733"></a>
+<span class="sourceLineNo">1734</span>  }<a name="line.1734"></a>
+<span class="sourceLineNo">1735</span><a name="line.1735"></a>
+<span class="sourceLineNo">1736</span>  /**<a name="line.1736"></a>
+<span class="sourceLineNo">1737</span>   * Compute the cost of total memstore size.  The more unbalanced the higher the<a name="line.1737"></a>
+<span class="sourceLineNo">1738</span>   * computed cost will be.  This uses a rolling average of regionload.<a name="line.1738"></a>
+<span class="sourceLineNo">1739</span>   */<a name="line.1739"></a>
+<span class="sourceLineNo">1740</span>  static class MemStoreSizeCostFunction extends CostFromRegionLoadAsRateFunction {<a name="line.1740"></a>
+<span class="sourceLineNo">1741</span><a name="line.1741"></a>
+<span class="sourceLineNo">1742</span>    private static final String MEMSTORE_SIZE_COST_KEY =<a name="line.1742"></a>
+<span class="sourceLineNo">1743</span>        "hbase.master.balancer.stochastic.memstoreSizeCost";<a name="line.1743"></a>
+<span class="sourceLineNo">1744</span>    private static final float DEFAULT_MEMSTORE_SIZE_COST = 5;<a name="line.1744"></a>
+<span class="sourceLineNo">1745</span><a name="line.1745"></a>
+<span class="sourceLineNo">1746</span>    MemStoreSizeCostFunction(Configuration conf) {<a name="line.1746"></a>
+<span class="sourceLineNo">1747</span>      super(conf);<a name="line.1747"></a>
+<span class="sourceLineNo">1748</span>      this.setMultiplier(conf.getFloat(MEMSTORE_SIZE_COST_KEY, DEFAULT_MEMSTORE_SIZE_COST));<a name="line.1748"></a>
+<span class="sourceLineNo">1749</span>    }<a name="line.1749"></a>
+<span class="sourceLineNo">1750</span><a name="line.1750"></a>
+<span class="sourceLineNo">1751</span>    @Override<a name="line.1751"></a>
+<span class="sourceLineNo">1752</span>    protected double getCostFromRl(BalancerRegionLoad rl) {<a name="line.1752"></a>
+<span class="sourceLineNo">1753</span>      return rl.getMemStoreSizeMB();<a name="line.1753"></a>
+<span class="sourceLineNo">1754</span>    }<a name="line.1754"></a>
+<span class="sourceLineNo">1755</span>  }<a name="line.1755"></a>
+<span class="sourceLineNo">1756</span><a name="line.1756"></a>
+<span class="sourceLineNo">1757</span>  /**<a name="line.1757"></a>
+<span class="sourceLineNo">1758</span>   * Compute the cost of total open storefiles size.  The more unbalanced the higher the<a name="line.1758"></a>
+<span class="sourceLineNo">1759</span>   * computed cost will be.  This uses a rolling average of regionload.<a name="line.1759"></a>
+<span class="sourceLineNo">1760</span>   */<a name="line.1760"></a>
+<span class="sourceLineNo">1761</span>  static class StoreFileCostFunction extends CostFromRegionLoadFunction {<a name="line.1761"></a>
+<span class="sourceLineNo">1762</span><a name="line.1762"></a>
+<span class="sourceLineNo">1763</span>    private static final String STOREFILE_SIZE_COST_KEY =<a name="line.1763"></a>
+<span class="sourceLineNo">1764</span>        "hbase.master.balancer.stochastic.storefileSizeCost";<a name="line.1764"></a>
+<span class="sourceLineNo">1765</span>    private static final float DEFAULT_STOREFILE_SIZE_COST = 5;<a name="line.1765"></a>
+<span class="sourceLineNo">1766</span><a name="line.1766"></a>
+<span class="sourceLineNo">1767</span>    StoreFileCostFunction(Configuration conf) {<a name="line.1767"></a>
+<span class="sourceLineNo">1768</span>      super(conf);<a name="line.1768"></a>
+<span class="sourceLineNo">1769</span>      this.setMultiplier(conf.getFloat(STOREFILE_SIZE_COST_KEY, DEFAULT_STOREFILE_SIZE_COST));<a name="line.1769"></a>
+<span class="sourceLineNo">1770</span>    }<a name="line.1770"></a>
+<span class="sourceLineNo">1771</span><a name="line.1771"></a>
+<span class="sourceLineNo">1772</span>    @Override<a name="line.1772"></a>
+<span class="sourceLineNo">1773</span>    protected double getCostFromRl(BalancerRegionLoad rl) {<a name="line.1773"></a>
+<span class="sourceLineNo">1774</span>      return rl.getStorefileSizeMB();<a name="line.1774"></a>
+<span class="sourceLineNo">1775</span>    }<a name="line.1775"></a>
+<span class="sourceLineNo">1776</span>  }<a name="line.1776"></a>
+<span class="sourceLineNo">1777</span><a name="line.1777"></a>
+<span class="sourceLineNo">1778</span>  /**<a name="line.1778"></a>
+<span class="sourceLineNo">1779</span>   * A helper function to compose the attribute name from tablename and costfunction name<a name="line.1779"></a>
+<span class="sourceLineNo">1780</span>   */<a name="line.1780"></a>
+<span class="sourceLineNo">1781</span>  public static String composeAttributeName(String tableName, String costFunctionName) {<a name="line.1781"></a>
+<span class="sourceLineNo">1782</span>    return tableName + TABLE_FUNCTION_SEP + costFunctionName;<a name="line.1782"></a>
+<span class="sourceLineNo">1783</span>  }<a name="line.1783"></a>
+<span class="sourceLineNo">1784</span>}<a name="line.1784"></a>
 
 
 
diff --git a/devapidocs/src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CostFromRegionLoadAsRateFunction.html b/devapidocs/src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CostFromRegionLoadAsRateFunction.html
index 4a9d7eb..7ce29c3 100644
--- a/devapidocs/src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CostFromRegionLoadAsRateFunction.html
+++ b/devapidocs/src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CostFromRegionLoadAsRateFunction.html
@@ -356,1438 +356,1440 @@
 <span class="sourceLineNo">348</span>    if (total &lt;= 0 || sumMultiplier &lt;= 0<a name="line.348"></a>
 <span class="sourceLineNo">349</span>        || (sumMultiplier &gt; 0 &amp;&amp; (total / sumMultiplier) &lt; minCostNeedBalance)) {<a name="line.349"></a>
 <span class="sourceLineNo">350</span>      if (LOG.isTraceEnabled()) {<a name="line.350"></a>
-<span class="sourceLineNo">351</span>        LOG.trace("Skipping load balancing because balanced cluster; " + "total cost is " + total<a name="line.351"></a>
-<span class="sourceLineNo">352</span>          + ", sum multiplier is " + sumMultiplier + " min cost which need balance is "<a name="line.352"></a>
-<span class="sourceLineNo">353</span>          + minCostNeedBalance);<a name="line.353"></a>
-<span class="sourceLineNo">354</span>      }<a name="line.354"></a>
-<span class="sourceLineNo">355</span>      return false;<a name="line.355"></a>
-<span class="sourceLineNo">356</span>    }<a name="line.356"></a>
-<span class="sourceLineNo">357</span>    return true;<a name="line.357"></a>
-<span class="sourceLineNo">358</span>  }<a name="line.358"></a>
-<span class="sourceLineNo">359</span><a name="line.359"></a>
-<span class="sourceLineNo">360</span>  @Override<a name="line.360"></a>
-<span class="sourceLineNo">361</span>  public synchronized List&lt;RegionPlan&gt; balanceCluster(TableName tableName, Map&lt;ServerName,<a name="line.361"></a>
-<span class="sourceLineNo">362</span>    List&lt;RegionInfo&gt;&gt; clusterState) {<a name="line.362"></a>
-<span class="sourceLineNo">363</span>    this.tableName = tableName;<a name="line.363"></a>
-<span class="sourceLineNo">364</span>    return balanceCluster(clusterState);<a name="line.364"></a>
-<span class="sourceLineNo">365</span>  }<a name="line.365"></a>
-<span class="sourceLineNo">366</span><a name="line.366"></a>
-<span class="sourceLineNo">367</span>  @VisibleForTesting<a name="line.367"></a>
-<span class="sourceLineNo">368</span>  Cluster.Action nextAction(Cluster cluster) {<a name="line.368"></a>
-<span class="sourceLineNo">369</span>    return candidateGenerators.get(RANDOM.nextInt(candidateGenerators.size()))<a name="line.369"></a>
-<span class="sourceLineNo">370</span>            .generate(cluster);<a name="line.370"></a>
-<span class="sourceLineNo">371</span>  }<a name="line.371"></a>
-<span class="sourceLineNo">372</span><a name="line.372"></a>
-<span class="sourceLineNo">373</span>  /**<a name="line.373"></a>
-<span class="sourceLineNo">374</span>   * Given the cluster state this will try and approach an optimal balance. This<a name="line.374"></a>
-<span class="sourceLineNo">375</span>   * should always approach the optimal state given enough steps.<a name="line.375"></a>
-<span class="sourceLineNo">376</span>   */<a name="line.376"></a>
-<span class="sourceLineNo">377</span>  @Override<a name="line.377"></a>
-<span class="sourceLineNo">378</span>  public synchronized List&lt;RegionPlan&gt; balanceCluster(Map&lt;ServerName,<a name="line.378"></a>
-<span class="sourceLineNo">379</span>    List&lt;RegionInfo&gt;&gt; clusterState) {<a name="line.379"></a>
-<span class="sourceLineNo">380</span>    List&lt;RegionPlan&gt; plans = balanceMasterRegions(clusterState);<a name="line.380"></a>
-<span class="sourceLineNo">381</span>    if (plans != null || clusterState == null || clusterState.size() &lt;= 1) {<a name="line.381"></a>
-<span class="sourceLineNo">382</span>      return plans;<a name="line.382"></a>
-<span class="sourceLineNo">383</span>    }<a name="line.383"></a>
-<span class="sourceLineNo">384</span><a name="line.384"></a>
-<span class="sourceLineNo">385</span>    if (masterServerName != null &amp;&amp; clusterState.containsKey(masterServerName)) {<a name="line.385"></a>
-<span class="sourceLineNo">386</span>      if (clusterState.size() &lt;= 2) {<a name="line.386"></a>
-<span class="sourceLineNo">387</span>        return null;<a name="line.387"></a>
-<span class="sourceLineNo">388</span>      }<a name="line.388"></a>
-<span class="sourceLineNo">389</span>      clusterState = new HashMap&lt;&gt;(clusterState);<a name="line.389"></a>
-<span class="sourceLineNo">390</span>      clusterState.remove(masterServerName);<a name="line.390"></a>
-<span class="sourceLineNo">391</span>    }<a name="line.391"></a>
-<span class="sourceLineNo">392</span><a name="line.392"></a>
-<span class="sourceLineNo">393</span>    // On clusters with lots of HFileLinks or lots of reference files,<a name="line.393"></a>
-<span class="sourceLineNo">394</span>    // instantiating the storefile infos can be quite expensive.<a name="line.394"></a>
-<span class="sourceLineNo">395</span>    // Allow turning this feature off if the locality cost is not going to<a name="line.395"></a>
-<span class="sourceLineNo">396</span>    // be used in any computations.<a name="line.396"></a>
-<span class="sourceLineNo">397</span>    RegionLocationFinder finder = null;<a name="line.397"></a>
-<span class="sourceLineNo">398</span>    if ((this.localityCost != null &amp;&amp; this.localityCost.getMultiplier() &gt; 0)<a name="line.398"></a>
-<span class="sourceLineNo">399</span>        || (this.rackLocalityCost != null &amp;&amp; this.rackLocalityCost.getMultiplier() &gt; 0)) {<a name="line.399"></a>
-<span class="sourceLineNo">400</span>      finder = this.regionFinder;<a name="line.400"></a>
-<span class="sourceLineNo">401</span>    }<a name="line.401"></a>
-<span class="sourceLineNo">402</span><a name="line.402"></a>
-<span class="sourceLineNo">403</span>    //The clusterState that is given to this method contains the state<a name="line.403"></a>
-<span class="sourceLineNo">404</span>    //of all the regions in the table(s) (that's true today)<a name="line.404"></a>
-<span class="sourceLineNo">405</span>    // Keep track of servers to iterate through them.<a name="line.405"></a>
-<span class="sourceLineNo">406</span>    Cluster cluster = new Cluster(clusterState, loads, finder, rackManager);<a name="line.406"></a>
-<span class="sourceLineNo">407</span><a name="line.407"></a>
-<span class="sourceLineNo">408</span>    long startTime = EnvironmentEdgeManager.currentTime();<a name="line.408"></a>
+<span class="sourceLineNo">351</span>        final String loadBalanceTarget =<a name="line.351"></a>
+<span class="sourceLineNo">352</span>            isByTable ? String.format("table (%s)", tableName) : "cluster";<a name="line.352"></a>
+<span class="sourceLineNo">353</span>        LOG.trace("Skipping load balancing because the {} is balanced. Total cost: {}, "<a name="line.353"></a>
+<span class="sourceLineNo">354</span>            + "Sum multiplier: {}, Minimum cost needed for balance: {}", loadBalanceTarget, total,<a name="line.354"></a>
+<span class="sourceLineNo">355</span>            sumMultiplier, minCostNeedBalance);<a name="line.355"></a>
+<span class="sourceLineNo">356</span>      }<a name="line.356"></a>
+<span class="sourceLineNo">357</span>      return false;<a name="line.357"></a>
+<span class="sourceLineNo">358</span>    }<a name="line.358"></a>
+<span class="sourceLineNo">359</span>    return true;<a name="line.359"></a>
+<span class="sourceLineNo">360</span>  }<a name="line.360"></a>
+<span class="sourceLineNo">361</span><a name="line.361"></a>
+<span class="sourceLineNo">362</span>  @Override<a name="line.362"></a>
+<span class="sourceLineNo">363</span>  public synchronized List&lt;RegionPlan&gt; balanceCluster(TableName tableName, Map&lt;ServerName,<a name="line.363"></a>
+<span class="sourceLineNo">364</span>    List&lt;RegionInfo&gt;&gt; clusterState) {<a name="line.364"></a>
+<span class="sourceLineNo">365</span>    this.tableName = tableName;<a name="line.365"></a>
+<span class="sourceLineNo">366</span>    return balanceCluster(clusterState);<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>  @VisibleForTesting<a name="line.369"></a>
+<span class="sourceLineNo">370</span>  Cluster.Action nextAction(Cluster cluster) {<a name="line.370"></a>
+<span class="sourceLineNo">371</span>    return candidateGenerators.get(RANDOM.nextInt(candidateGenerators.size()))<a name="line.371"></a>
+<span class="sourceLineNo">372</span>            .generate(cluster);<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>  /**<a name="line.375"></a>
+<span class="sourceLineNo">376</span>   * Given the cluster state this will try and approach an optimal balance. This<a name="line.376"></a>
+<span class="sourceLineNo">377</span>   * should always approach the optimal state given enough steps.<a name="line.377"></a>
+<span class="sourceLineNo">378</span>   */<a name="line.378"></a>
+<span class="sourceLineNo">379</span>  @Override<a name="line.379"></a>
+<span class="sourceLineNo">380</span>  public synchronized List&lt;RegionPlan&gt; balanceCluster(Map&lt;ServerName,<a name="line.380"></a>
+<span class="sourceLineNo">381</span>    List&lt;RegionInfo&gt;&gt; clusterState) {<a name="line.381"></a>
+<span class="sourceLineNo">382</span>    List&lt;RegionPlan&gt; plans = balanceMasterRegions(clusterState);<a name="line.382"></a>
+<span class="sourceLineNo">383</span>    if (plans != null || clusterState == null || clusterState.size() &lt;= 1) {<a name="line.383"></a>
+<span class="sourceLineNo">384</span>      return plans;<a name="line.384"></a>
+<span class="sourceLineNo">385</span>    }<a name="line.385"></a>
+<span class="sourceLineNo">386</span><a name="line.386"></a>
+<span class="sourceLineNo">387</span>    if (masterServerName != null &amp;&amp; clusterState.containsKey(masterServerName)) {<a name="line.387"></a>
+<span class="sourceLineNo">388</span>      if (clusterState.size() &lt;= 2) {<a name="line.388"></a>
+<span class="sourceLineNo">389</span>        return null;<a name="line.389"></a>
+<span class="sourceLineNo">390</span>      }<a name="line.390"></a>
+<span class="sourceLineNo">391</span>      clusterState = new HashMap&lt;&gt;(clusterState);<a name="line.391"></a>
+<span class="sourceLineNo">392</span>      clusterState.remove(masterServerName);<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>    // On clusters with lots of HFileLinks or lots of reference files,<a name="line.395"></a>
+<span class="sourceLineNo">396</span>    // instantiating the storefile infos can be quite expensive.<a name="line.396"></a>
+<span class="sourceLineNo">397</span>    // Allow turning this feature off if the locality cost is not going to<a name="line.397"></a>
+<span class="sourceLineNo">398</span>    // be used in any computations.<a name="line.398"></a>
+<span class="sourceLineNo">399</span>    RegionLocationFinder finder = null;<a name="line.399"></a>
+<span class="sourceLineNo">400</span>    if ((this.localityCost != null &amp;&amp; this.localityCost.getMultiplier() &gt; 0)<a name="line.400"></a>
+<span class="sourceLineNo">401</span>        || (this.rackLocalityCost != null &amp;&amp; this.rackLocalityCost.getMultiplier() &gt; 0)) {<a name="line.401"></a>
+<span class="sourceLineNo">402</span>      finder = this.regionFinder;<a name="line.402"></a>
+<span class="sourceLineNo">403</span>    }<a name="line.403"></a>
+<span class="sourceLineNo">404</span><a name="line.404"></a>
+<span class="sourceLineNo">405</span>    //The clusterState that is given to this method contains the state<a name="line.405"></a>
+<span class="sourceLineNo">406</span>    //of all the regions in the table(s) (that's true today)<a name="line.406"></a>
+<span class="sourceLineNo">407</span>    // Keep track of servers to iterate through them.<a name="line.407"></a>
+<span class="sourceLineNo">408</span>    Cluster cluster = new Cluster(clusterState, loads, finder, rackManager);<a name="line.408"></a>
 <span class="sourceLineNo">409</span><a name="line.409"></a>
-<span class="sourceLineNo">410</span>    initCosts(cluster);<a name="line.410"></a>
+<span class="sourceLineNo">410</span>    long startTime = EnvironmentEdgeManager.currentTime();<a name="line.410"></a>
 <span class="sourceLineNo">411</span><a name="line.411"></a>
-<span class="sourceLineNo">412</span>    if (!needsBalance(cluster)) {<a name="line.412"></a>
-<span class="sourceLineNo">413</span>      return null;<a name="line.413"></a>
-<span class="sourceLineNo">414</span>    }<a name="line.414"></a>
-<span class="sourceLineNo">415</span><a name="line.415"></a>
-<span class="sourceLineNo">416</span>    double currentCost = computeCost(cluster, Double.MAX_VALUE);<a name="line.416"></a>
-<span class="sourceLineNo">417</span>    curOverallCost = currentCost;<a name="line.417"></a>
-<span class="sourceLineNo">418</span>    for (int i = 0; i &lt; this.curFunctionCosts.length; i++) {<a name="line.418"></a>
-<span class="sourceLineNo">419</span>      curFunctionCosts[i] = tempFunctionCosts[i];<a name="line.419"></a>
-<span class="sourceLineNo">420</span>    }<a name="line.420"></a>
-<span class="sourceLineNo">421</span>    double initCost = currentCost;<a name="line.421"></a>
-<span class="sourceLineNo">422</span>    double newCost = currentCost;<a name="line.422"></a>
-<span class="sourceLineNo">423</span><a name="line.423"></a>
-<span class="sourceLineNo">424</span>    long computedMaxSteps;<a name="line.424"></a>
-<span class="sourceLineNo">425</span>    if (runMaxSteps) {<a name="line.425"></a>
-<span class="sourceLineNo">426</span>      computedMaxSteps = Math.max(this.maxSteps,<a name="line.426"></a>
-<span class="sourceLineNo">427</span>          ((long)cluster.numRegions * (long)this.stepsPerRegion * (long)cluster.numServers));<a name="line.427"></a>
-<span class="sourceLineNo">428</span>    } else {<a name="line.428"></a>
-<span class="sourceLineNo">429</span>      long calculatedMaxSteps = (long)cluster.numRegions * (long)this.stepsPerRegion *<a name="line.429"></a>
-<span class="sourceLineNo">430</span>          (long)cluster.numServers;<a name="line.430"></a>
-<span class="sourceLineNo">431</span>      computedMaxSteps = Math.min(this.maxSteps, calculatedMaxSteps);<a name="line.431"></a>
-<span class="sourceLineNo">432</span>      if (calculatedMaxSteps &gt; maxSteps) {<a name="line.432"></a>
-<span class="sourceLineNo">433</span>        LOG.warn("calculatedMaxSteps:{} for loadbalancer's stochastic walk is larger than "<a name="line.433"></a>
-<span class="sourceLineNo">434</span>            + "maxSteps:{}. Hence load balancing may not work well. Setting parameter "<a name="line.434"></a>
-<span class="sourceLineNo">435</span>            + "\"hbase.master.balancer.stochastic.runMaxSteps\" to true can overcome this issue."<a name="line.435"></a>
-<span class="sourceLineNo">436</span>            + "(This config change does not require service restart)", calculatedMaxSteps,<a name="line.436"></a>
-<span class="sourceLineNo">437</span>            maxSteps);<a name="line.437"></a>
-<span class="sourceLineNo">438</span>      }<a name="line.438"></a>
-<span class="sourceLineNo">439</span>    }<a name="line.439"></a>
-<span class="sourceLineNo">440</span>    LOG.info("start StochasticLoadBalancer.balancer, initCost=" + currentCost + ", functionCost="<a name="line.440"></a>
-<span class="sourceLineNo">441</span>        + functionCost() + " computedMaxSteps: " + computedMaxSteps);<a name="line.441"></a>
-<span class="sourceLineNo">442</span><a name="line.442"></a>
-<span class="sourceLineNo">443</span>    // Perform a stochastic walk to see if we can get a good fit.<a name="line.443"></a>
-<span class="sourceLineNo">444</span>    long step;<a name="line.444"></a>
-<span class="sourceLineNo">445</span><a name="line.445"></a>
-<span class="sourceLineNo">446</span>    for (step = 0; step &lt; computedMaxSteps; step++) {<a name="line.446"></a>
-<span class="sourceLineNo">447</span>      Cluster.Action action = nextAction(cluster);<a name="line.447"></a>
-<span class="sourceLineNo">448</span><a name="line.448"></a>
-<span class="sourceLineNo">449</span>      if (action.type == Type.NULL) {<a name="line.449"></a>
-<span class="sourceLineNo">450</span>        continue;<a name="line.450"></a>
-<span class="sourceLineNo">451</span>      }<a name="line.451"></a>
-<span class="sourceLineNo">452</span><a name="line.452"></a>
-<span class="sourceLineNo">453</span>      cluster.doAction(action);<a name="line.453"></a>
-<span class="sourceLineNo">454</span>      updateCostsWithAction(cluster, action);<a name="line.454"></a>
-<span class="sourceLineNo">455</span><a name="line.455"></a>
-<span class="sourceLineNo">456</span>      newCost = computeCost(cluster, currentCost);<a name="line.456"></a>
+<span class="sourceLineNo">412</span>    initCosts(cluster);<a name="line.412"></a>
+<span class="sourceLineNo">413</span><a name="line.413"></a>
+<span class="sourceLineNo">414</span>    if (!needsBalance(cluster)) {<a name="line.414"></a>
+<span class="sourceLineNo">415</span>      return null;<a name="line.415"></a>
+<span class="sourceLineNo">416</span>    }<a name="line.416"></a>
+<span class="sourceLineNo">417</span><a name="line.417"></a>
+<span class="sourceLineNo">418</span>    double currentCost = computeCost(cluster, Double.MAX_VALUE);<a name="line.418"></a>
+<span class="sourceLineNo">419</span>    curOverallCost = currentCost;<a name="line.419"></a>
+<span class="sourceLineNo">420</span>    for (int i = 0; i &lt; this.curFunctionCosts.length; i++) {<a name="line.420"></a>
+<span class="sourceLineNo">421</span>      curFunctionCosts[i] = tempFunctionCosts[i];<a name="line.421"></a>
+<span class="sourceLineNo">422</span>    }<a name="line.422"></a>
+<span class="sourceLineNo">423</span>    double initCost = currentCost;<a name="line.423"></a>
+<span class="sourceLineNo">424</span>    double newCost = currentCost;<a name="line.424"></a>
+<span class="sourceLineNo">425</span><a name="line.425"></a>
+<span class="sourceLineNo">426</span>    long computedMaxSteps;<a name="line.426"></a>
+<span class="sourceLineNo">427</span>    if (runMaxSteps) {<a name="line.427"></a>
+<span class="sourceLineNo">428</span>      computedMaxSteps = Math.max(this.maxSteps,<a name="line.428"></a>
+<span class="sourceLineNo">429</span>          ((long)cluster.numRegions * (long)this.stepsPerRegion * (long)cluster.numServers));<a name="line.429"></a>
+<span class="sourceLineNo">430</span>    } else {<a name="line.430"></a>
+<span class="sourceLineNo">431</span>      long calculatedMaxSteps = (long)cluster.numRegions * (long)this.stepsPerRegion *<a name="line.431"></a>
+<span class="sourceLineNo">432</span>          (long)cluster.numServers;<a name="line.432"></a>
+<span class="sourceLineNo">433</span>      computedMaxSteps = Math.min(this.maxSteps, calculatedMaxSteps);<a name="line.433"></a>
+<span class="sourceLineNo">434</span>      if (calculatedMaxSteps &gt; maxSteps) {<a name="line.434"></a>
+<span class="sourceLineNo">435</span>        LOG.warn("calculatedMaxSteps:{} for loadbalancer's stochastic walk is larger than "<a name="line.435"></a>
+<span class="sourceLineNo">436</span>            + "maxSteps:{}. Hence load balancing may not work well. Setting parameter "<a name="line.436"></a>
+<span class="sourceLineNo">437</span>            + "\"hbase.master.balancer.stochastic.runMaxSteps\" to true can overcome this issue."<a name="line.437"></a>
+<span class="sourceLineNo">438</span>            + "(This config change does not require service restart)", calculatedMaxSteps,<a name="line.438"></a>
+<span class="sourceLineNo">439</span>            maxSteps);<a name="line.439"></a>
+<span class="sourceLineNo">440</span>      }<a name="line.440"></a>
+<span class="sourceLineNo">441</span>    }<a name="line.441"></a>
+<span class="sourceLineNo">442</span>    LOG.info("start StochasticLoadBalancer.balancer, initCost=" + currentCost + ", functionCost="<a name="line.442"></a>
+<span class="sourceLineNo">443</span>        + functionCost() + " computedMaxSteps: " + computedMaxSteps);<a name="line.443"></a>
+<span class="sourceLineNo">444</span><a name="line.444"></a>
+<span class="sourceLineNo">445</span>    // Perform a stochastic walk to see if we can get a good fit.<a name="line.445"></a>
+<span class="sourceLineNo">446</span>    long step;<a name="line.446"></a>
+<span class="sourceLineNo">447</span><a name="line.447"></a>
+<span class="sourceLineNo">448</span>    for (step = 0; step &lt; computedMaxSteps; step++) {<a name="line.448"></a>
+<span class="sourceLineNo">449</span>      Cluster.Action action = nextAction(cluster);<a name="line.449"></a>
+<span class="sourceLineNo">450</span><a name="line.450"></a>
+<span class="sourceLineNo">451</span>      if (action.type == Type.NULL) {<a name="line.451"></a>
+<span class="sourceLineNo">452</span>        continue;<a name="line.452"></a>
+<span class="sourceLineNo">453</span>      }<a name="line.453"></a>
+<span class="sourceLineNo">454</span><a name="line.454"></a>
+<span class="sourceLineNo">455</span>      cluster.doAction(action);<a name="line.455"></a>
+<span class="sourceLineNo">456</span>      updateCostsWithAction(cluster, action);<a name="line.456"></a>
 <span class="sourceLineNo">457</span><a name="line.457"></a>
-<span class="sourceLineNo">458</span>      // Should this be kept?<a name="line.458"></a>
-<span class="sourceLineNo">459</span>      if (newCost &lt; currentCost) {<a name="line.459"></a>
-<span class="sourceLineNo">460</span>        currentCost = newCost;<a name="line.460"></a>
-<span class="sourceLineNo">461</span><a name="line.461"></a>
-<span class="sourceLineNo">462</span>        // save for JMX<a name="line.462"></a>
-<span class="sourceLineNo">463</span>        curOverallCost = currentCost;<a name="line.463"></a>
-<span class="sourceLineNo">464</span>        for (int i = 0; i &lt; this.curFunctionCosts.length; i++) {<a name="line.464"></a>
-<span class="sourceLineNo">465</span>          curFunctionCosts[i] = tempFunctionCosts[i];<a name="line.465"></a>
-<span class="sourceLineNo">466</span>        }<a name="line.466"></a>
-<span class="sourceLineNo">467</span>      } else {<a name="line.467"></a>
-<span class="sourceLineNo">468</span>        // Put things back the way they were before.<a name="line.468"></a>
-<span class="sourceLineNo">469</span>        // TODO: undo by remembering old values<a name="line.469"></a>
-<span class="sourceLineNo">470</span>        Action undoAction = action.undoAction();<a name="line.470"></a>
-<span class="sourceLineNo">471</span>        cluster.doAction(undoAction);<a name="line.471"></a>
-<span class="sourceLineNo">472</span>        updateCostsWithAction(cluster, undoAction);<a name="line.472"></a>
-<span class="sourceLineNo">473</span>      }<a name="line.473"></a>
-<span class="sourceLineNo">474</span><a name="line.474"></a>
-<span class="sourceLineNo">475</span>      if (EnvironmentEdgeManager.currentTime() - startTime &gt;<a name="line.475"></a>
-<span class="sourceLineNo">476</span>          maxRunningTime) {<a name="line.476"></a>
-<span class="sourceLineNo">477</span>        break;<a name="line.477"></a>
-<span class="sourceLineNo">478</span>      }<a name="line.478"></a>
-<span class="sourceLineNo">479</span>    }<a name="line.479"></a>
-<span class="sourceLineNo">480</span>    long endTime = EnvironmentEdgeManager.currentTime();<a name="line.480"></a>
-<span class="sourceLineNo">481</span><a name="line.481"></a>
-<span class="sourceLineNo">482</span>    metricsBalancer.balanceCluster(endTime - startTime);<a name="line.482"></a>
+<span class="sourceLineNo">458</span>      newCost = computeCost(cluster, currentCost);<a name="line.458"></a>
+<span class="sourceLineNo">459</span><a name="line.459"></a>
+<span class="sourceLineNo">460</span>      // Should this be kept?<a name="line.460"></a>
+<span class="sourceLineNo">461</span>      if (newCost &lt; currentCost) {<a name="line.461"></a>
+<span class="sourceLineNo">462</span>        currentCost = newCost;<a name="line.462"></a>
+<span class="sourceLineNo">463</span><a name="line.463"></a>
+<span class="sourceLineNo">464</span>        // save for JMX<a name="line.464"></a>
+<span class="sourceLineNo">465</span>        curOverallCost = currentCost;<a name="line.465"></a>
+<span class="sourceLineNo">466</span>        for (int i = 0; i &lt; this.curFunctionCosts.length; i++) {<a name="line.466"></a>
+<span class="sourceLineNo">467</span>          curFunctionCosts[i] = tempFunctionCosts[i];<a name="line.467"></a>
+<span class="sourceLineNo">468</span>        }<a name="line.468"></a>
+<span class="sourceLineNo">469</span>      } else {<a name="line.469"></a>
+<span class="sourceLineNo">470</span>        // Put things back the way they were before.<a name="line.470"></a>
+<span class="sourceLineNo">471</span>        // TODO: undo by remembering old values<a name="line.471"></a>
+<span class="sourceLineNo">472</span>        Action undoAction = action.undoAction();<a name="line.472"></a>
+<span class="sourceLineNo">473</span>        cluster.doAction(undoAction);<a name="line.473"></a>
+<span class="sourceLineNo">474</span>        updateCostsWithAction(cluster, undoAction);<a name="line.474"></a>
+<span class="sourceLineNo">475</span>      }<a name="line.475"></a>
+<span class="sourceLineNo">476</span><a name="line.476"></a>
+<span class="sourceLineNo">477</span>      if (EnvironmentEdgeManager.currentTime() - startTime &gt;<a name="line.477"></a>
+<span class="sourceLineNo">478</span>          maxRunningTime) {<a name="line.478"></a>
+<span class="sourceLineNo">479</span>        break;<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>    long endTime = EnvironmentEdgeManager.currentTime();<a name="line.482"></a>
 <span class="sourceLineNo">483</span><a name="line.483"></a>
-<span class="sourceLineNo">484</span>    // update costs metrics<a name="line.484"></a>
-<span class="sourceLineNo">485</span>    updateStochasticCosts(tableName, curOverallCost, curFunctionCosts);<a name="line.485"></a>
-<span class="sourceLineNo">486</span>    if (initCost &gt; currentCost) {<a name="line.486"></a>
-<span class="sourceLineNo">487</span>      plans = createRegionPlans(cluster);<a name="line.487"></a>
-<span class="sourceLineNo">488</span>      LOG.info("Finished computing new load balance plan. Computation took {}" +<a name="line.488"></a>
-<span class="sourceLineNo">489</span>        " to try {} different iterations.  Found a solution that moves " +<a name="line.489"></a>
-<span class="sourceLineNo">490</span>        "{} regions; Going from a computed cost of {}" +<a name="line.490"></a>
-<span class="sourceLineNo">491</span>        " to a new cost of {}", java.time.Duration.ofMillis(endTime - startTime),<a name="line.491"></a>
-<span class="sourceLineNo">492</span>        step, plans.size(), initCost, currentCost);<a name="line.492"></a>
-<span class="sourceLineNo">493</span>      return plans;<a name="line.493"></a>
-<span class="sourceLineNo">494</span>    }<a name="line.494"></a>
-<span class="sourceLineNo">495</span>    LOG.info("Could not find a better load balance plan.  Tried {} different configurations in " +<a name="line.495"></a>
-<span class="sourceLineNo">496</span>      "{}, and did not find anything with a computed cost less than {}", step,<a name="line.496"></a>
-<span class="sourceLineNo">497</span>      java.time.Duration.ofMillis(endTime - startTime), initCost);<a name="line.497"></a>
-<span class="sourceLineNo">498</span>    return null;<a name="line.498"></a>
-<span class="sourceLineNo">499</span>  }<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>   * update costs to JMX<a name="line.502"></a>
-<span class="sourceLineNo">503</span>   */<a name="line.503"></a>
-<span class="sourceLineNo">504</span>  private void updateStochasticCosts(TableName tableName, Double overall, Double[] subCosts) {<a name="line.504"></a>
-<span class="sourceLineNo">505</span>    if (tableName == null) return;<a name="line.505"></a>
-<span class="sourceLineNo">506</span><a name="line.506"></a>
-<span class="sourceLineNo">507</span>    // check if the metricsBalancer is MetricsStochasticBalancer before casting<a name="line.507"></a>
-<span class="sourceLineNo">508</span>    if (metricsBalancer instanceof MetricsStochasticBalancer) {<a name="line.508"></a>
-<span class="sourceLineNo">509</span>      MetricsStochasticBalancer balancer = (MetricsStochasticBalancer) metricsBalancer;<a name="line.509"></a>
-<span class="sourceLineNo">510</span>      // overall cost<a name="line.510"></a>
-<span class="sourceLineNo">511</span>      balancer.updateStochasticCost(tableName.getNameAsString(),<a name="line.511"></a>
-<span class="sourceLineNo">512</span>        "Overall", "Overall cost", overall);<a name="line.512"></a>
-<span class="sourceLineNo">513</span><a name="line.513"></a>
-<span class="sourceLineNo">514</span>      // each cost function<a name="line.514"></a>
-<span class="sourceLineNo">515</span>      for (int i = 0; i &lt; costFunctions.size(); i++) {<a name="line.515"></a>
-<span class="sourceLineNo">516</span>        CostFunction costFunction = costFunctions.get(i);<a name="line.516"></a>
-<span class="sourceLineNo">517</span>        String costFunctionName = costFunction.getClass().getSimpleName();<a name="line.517"></a>
-<span class="sourceLineNo">518</span>        Double costPercent = (overall == 0) ? 0 : (subCosts[i] / overall);<a name="line.518"></a>
-<span class="sourceLineNo">519</span>        // TODO: cost function may need a specific description<a name="line.519"></a>
-<span class="sourceLineNo">520</span>        balancer.updateStochasticCost(tableName.getNameAsString(), costFunctionName,<a name="line.520"></a>
-<span class="sourceLineNo">521</span>          "The percent of " + costFunctionName, costPercent);<a name="line.521"></a>
-<span class="sourceLineNo">522</span>      }<a name="line.522"></a>
-<span class="sourceLineNo">523</span>    }<a name="line.523"></a>
-<span class="sourceLineNo">524</span>  }<a name="line.524"></a>
-<span class="sourceLineNo">525</span><a name="line.525"></a>
-<span class="sourceLineNo">526</span>  private String functionCost() {<a name="line.526"></a>
-<span class="sourceLineNo">527</span>    StringBuilder builder = new StringBuilder();<a name="line.527"></a>
-<span class="sourceLineNo">528</span>    for (CostFunction c:costFunctions) {<a name="line.528"></a>
-<span class="sourceLineNo">529</span>      builder.append(c.getClass().getSimpleName());<a name="line.529"></a>
-<span class="sourceLineNo">530</span>      builder.append(" : (");<a name="line.530"></a>
-<span class="sourceLineNo">531</span>      builder.append(c.getMultiplier());<a name="line.531"></a>
-<span class="sourceLineNo">532</span>      builder.append(", ");<a name="line.532"></a>
-<span class="sourceLineNo">533</span>      builder.append(c.cost());<a name="line.533"></a>
-<span class="sourceLineNo">534</span>      builder.append("); ");<a name="line.534"></a>
-<span class="sourceLineNo">535</span>    }<a name="line.535"></a>
-<span class="sourceLineNo">536</span>    return builder.toString();<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>  /**<a name="line.539"></a>
-<span class="sourceLineNo">540</span>   * Create all of the RegionPlan's needed to move from the initial cluster state to the desired<a name="line.540"></a>
-<span class="sourceLineNo">541</span>   * state.<a name="line.541"></a>
-<span class="sourceLineNo">542</span>   *<a name="line.542"></a>
-<span class="sourceLineNo">543</span>   * @param cluster The state of the cluster<a name="line.543"></a>
-<span class="sourceLineNo">544</span>   * @return List of RegionPlan's that represent the moves needed to get to desired final state.<a name="line.544"></a>
-<span class="sourceLineNo">545</span>   */<a name="line.545"></a>
-<span class="sourceLineNo">546</span>  private List&lt;RegionPlan&gt; createRegionPlans(Cluster cluster) {<a name="line.546"></a>
-<span class="sourceLineNo">547</span>    List&lt;RegionPlan&gt; plans = new LinkedList&lt;&gt;();<a name="line.547"></a>
-<span class="sourceLineNo">548</span>    for (int regionIndex = 0;<a name="line.548"></a>
-<span class="sourceLineNo">549</span>         regionIndex &lt; cluster.regionIndexToServerIndex.length; regionIndex++) {<a name="line.549"></a>
-<span class="sourceLineNo">550</span>      int initialServerIndex = cluster.initialRegionIndexToServerIndex[regionIndex];<a name="line.550"></a>
-<span class="sourceLineNo">551</span>      int newServerIndex = cluster.regionIndexToServerIndex[regionIndex];<a name="line.551"></a>
-<span class="sourceLineNo">552</span><a name="line.552"></a>
-<span class="sourceLineNo">553</span>      if (initialServerIndex != newServerIndex) {<a name="line.553"></a>
-<span class="sourceLineNo">554</span>        RegionInfo region = cluster.regions[regionIndex];<a name="line.554"></a>
-<span class="sourceLineNo">555</span>        ServerName initialServer = cluster.servers[initialServerIndex];<a name="line.555"></a>
-<span class="sourceLineNo">556</span>        ServerName newServer = cluster.servers[newServerIndex];<a name="line.556"></a>
-<span class="sourceLineNo">557</span><a name="line.557"></a>
-<span class="sourceLineNo">558</span>        if (LOG.isTraceEnabled()) {<a name="line.558"></a>
-<span class="sourceLineNo">559</span>          LOG.trace("Moving Region " + region.getEncodedName() + " from server "<a name="line.559"></a>
-<span class="sourceLineNo">560</span>              + initialServer.getHostname() + " to " + newServer.getHostname());<a name="line.560"></a>
-<span class="sourceLineNo">561</span>        }<a name="line.561"></a>
-<span class="sourceLineNo">562</span>        RegionPlan rp = new RegionPlan(region, initialServer, newServer);<a name="line.562"></a>
-<span class="sourceLineNo">563</span>        plans.add(rp);<a name="line.563"></a>
-<span class="sourceLineNo">564</span>      }<a name="line.564"></a>
-<span class="sourceLineNo">565</span>    }<a name="line.565"></a>
-<span class="sourceLineNo">566</span>    return plans;<a name="line.566"></a>
-<span class="sourceLineNo">567</span>  }<a name="line.567"></a>
-<span class="sourceLineNo">568</span><a name="line.568"></a>
-<span class="sourceLineNo">569</span>  /**<a name="line.569"></a>
-<span class="sourceLineNo">570</span>   * Store the current region loads.<a name="line.570"></a>
-<span class="sourceLineNo">571</span>   */<a name="line.571"></a>
-<span class="sourceLineNo">572</span>  private synchronized void updateRegionLoad() {<a name="line.572"></a>
-<span class="sourceLineNo">573</span>    // We create a new hashmap so that regions that are no longer there are removed.<a name="line.573"></a>
-<span class="sourceLineNo">574</span>    // However we temporarily need the old loads so we can use them to keep the rolling average.<a name="line.574"></a>
-<span class="sourceLineNo">575</span>    Map&lt;String, Deque&lt;BalancerRegionLoad&gt;&gt; oldLoads = loads;<a name="line.575"></a>
-<span class="sourceLineNo">576</span>    loads = new HashMap&lt;&gt;();<a name="line.576"></a>
-<span class="sourceLineNo">577</span><a name="line.577"></a>
-<span class="sourceLineNo">578</span>    clusterStatus.getLiveServerMetrics().forEach((ServerName sn, ServerMetrics sm) -&gt; {<a name="line.578"></a>
-<span class="sourceLineNo">579</span>      sm.getRegionMetrics().forEach((byte[] regionName, RegionMetrics rm) -&gt; {<a name="line.579"></a>
-<span class="sourceLineNo">580</span>        String regionNameAsString = RegionInfo.getRegionNameAsString(regionName);<a name="line.580"></a>
-<span class="sourceLineNo">581</span>        Deque&lt;BalancerRegionLoad&gt; rLoads = oldLoads.get(regionNameAsString);<a name="line.581"></a>
-<span class="sourceLineNo">582</span>        if (rLoads == null) {<a name="line.582"></a>
-<span class="sourceLineNo">583</span>          rLoads = new ArrayDeque&lt;&gt;(numRegionLoadsToRemember + 1);<a name="line.583"></a>
-<span class="sourceLineNo">584</span>        } else if (rLoads.size() &gt;= numRegionLoadsToRemember) {<a name="line.584"></a>
-<span class="sourceLineNo">585</span>          rLoads.remove();<a name="line.585"></a>
-<span class="sourceLineNo">586</span>        }<a name="line.586"></a>
-<span class="sourceLineNo">587</span>        rLoads.add(new BalancerRegionLoad(rm));<a name="line.587"></a>
-<span class="sourceLineNo">588</span>        loads.put(regionNameAsString, rLoads);<a name="line.588"></a>
-<span class="sourceLineNo">589</span>      });<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>    for(CostFromRegionLoadFunction cost : regionLoadFunctions) {<a name="line.592"></a>
-<span class="sourceLineNo">593</span>      cost.setLoads(loads);<a name="line.593"></a>
-<span class="sourceLineNo">594</span>    }<a name="line.594"></a>
-<span class="sourceLineNo">595</span>  }<a name="line.595"></a>
-<span class="sourceLineNo">596</span><a name="line.596"></a>
-<span class="sourceLineNo">597</span>  protected void initCosts(Cluster cluster) {<a name="line.597"></a>
-<span class="sourceLineNo">598</span>    for (CostFunction c:costFunctions) {<a name="line.598"></a>
-<span class="sourceLineNo">599</span>      c.init(cluster);<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>  protected void updateCostsWithAction(Cluster cluster, Action action) {<a name="line.603"></a>
-<span class="sourceLineNo">604</span>    for (CostFunction c : costFunctions) {<a name="line.604"></a>
-<span class="sourceLineNo">605</span>      c.postAction(action);<a name="line.605"></a>
-<span class="sourceLineNo">606</span>    }<a name="line.606"></a>
-<span class="sourceLineNo">607</span>  }<a name="line.607"></a>
-<span class="sourceLineNo">608</span><a name="line.608"></a>
-<span class="sourceLineNo">609</span>  /**<a name="line.609"></a>
-<span class="sourceLineNo">610</span>   * Get the names of the cost functions<a name="line.610"></a>
-<span class="sourceLineNo">611</span>   */<a name="line.611"></a>
-<span class="sourceLineNo">612</span>  public String[] getCostFunctionNames() {<a name="line.612"></a>
-<span class="sourceLineNo">613</span>    if (costFunctions == null) return null;<a name="line.613"></a>
-<span class="sourceLineNo">614</span>    String[] ret = new String[costFunctions.size()];<a name="line.614"></a>
-<span class="sourceLineNo">615</span>    for (int i = 0; i &lt; costFunctions.size(); i++) {<a name="line.615"></a>
-<span class="sourceLineNo">616</span>      CostFunction c = costFunctions.get(i);<a name="line.616"></a>
-<span class="sourceLineNo">617</span>      ret[i] = c.getClass().getSimpleName();<a name="line.617"></a>
-<span class="sourceLineNo">618</span>    }<a name="line.618"></a>
-<span class="sourceLineNo">619</span><a name="line.619"></a>
-<span class="sourceLineNo">620</span>    return ret;<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>   * This is the main cost function.  It will compute a cost associated with a proposed cluster<a name="line.624"></a>
-<span class="sourceLineNo">625</span>   * state.  All different costs will be combined with their multipliers to produce a double cost.<a name="line.625"></a>
-<span class="sourceLineNo">626</span>   *<a name="line.626"></a>
-<span class="sourceLineNo">627</span>   * @param cluster The state of the cluster<a name="line.627"></a>
-<span class="sourceLineNo">628</span>   * @param previousCost the previous cost. This is used as an early out.<a name="line.628"></a>
-<span class="sourceLineNo">629</span>   * @return a double of a cost associated with the proposed cluster state.  This cost is an<a name="line.629"></a>
-<span class="sourceLineNo">630</span>   *         aggregate of all individual cost functions.<a name="line.630"></a>
-<span class="sourceLineNo">631</span>   */<a name="line.631"></a>
-<span class="sourceLineNo">632</span>  protected double computeCost(Cluster cluster, double previousCost) {<a name="line.632"></a>
-<span class="sourceLineNo">633</span>    double total = 0;<a name="line.633"></a>
-<span class="sourceLineNo">634</span><a name="line.634"></a>
-<span class="sourceLineNo">635</span>    for (int i = 0; i &lt; costFunctions.size(); i++) {<a name="line.635"></a>
-<span class="sourceLineNo">636</span>      CostFunction c = costFunctions.get(i);<a name="line.636"></a>
-<span class="sourceLineNo">637</span>      this.tempFunctionCosts[i] = 0.0;<a name="line.637"></a>
-<span class="sourceLineNo">638</span><a name="line.638"></a>
-<span class="sourceLineNo">639</span>      if (c.getMultiplier() &lt;= 0) {<a name="line.639"></a>
-<span class="sourceLineNo">640</span>        continue;<a name="line.640"></a>
-<span class="sourceLineNo">641</span>      }<a name="line.641"></a>
-<span class="sourceLineNo">642</span><a name="line.642"></a>
-<span class="sourceLineNo">643</span>      Float multiplier = c.getMultiplier();<a name="line.643"></a>
-<span class="sourceLineNo">644</span>      Double cost = c.cost();<a name="line.644"></a>
-<span class="sourceLineNo">645</span><a name="line.645"></a>
-<span class="sourceLineNo">646</span>      this.tempFunctionCosts[i] = multiplier*cost;<a name="line.646"></a>
-<span class="sourceLineNo">647</span>      total += this.tempFunctionCosts[i];<a name="line.647"></a>
-<span class="sourceLineNo">648</span><a name="line.648"></a>
-<span class="sourceLineNo">649</span>      if (total &gt; previousCost) {<a name="line.649"></a>
-<span class="sourceLineNo">650</span>        break;<a name="line.650"></a>
-<span class="sourceLineNo">651</span>      }<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>    return total;<a name="line.654"></a>
-<span class="sourceLineNo">655</span>  }<a name="line.655"></a>
-<span class="sourceLineNo">656</span><a name="line.656"></a>
-<span class="sourceLineNo">657</span>  /** Generates a candidate action to be applied to the cluster for cost function search */<a name="line.657"></a>
-<span class="sourceLineNo">658</span>  abstract static class CandidateGenerator {<a name="line.658"></a>
-<span class="sourceLineNo">659</span>    abstract Cluster.Action generate(Cluster cluster);<a name="line.659"></a>
-<span class="sourceLineNo">660</span><a name="line.660"></a>
-<span class="sourceLineNo">661</span>    /**<a name="line.661"></a>
-<span class="sourceLineNo">662</span>     * From a list of regions pick a random one. Null can be returned which<a name="line.662"></a>
-<span class="sourceLineNo">663</span>     * {@link StochasticLoadBalancer#balanceCluster(Map)} recognize as signal to try a region move<a name="line.663"></a>
-<span class="sourceLineNo">664</span>     * rather than swap.<a name="line.664"></a>
-<span class="sourceLineNo">665</span>     *<a name="line.665"></a>
-<span class="sourceLineNo">666</span>     * @param cluster        The state of the cluster<a name="line.666"></a>
-<span class="sourceLineNo">667</span>     * @param server         index of the server<a name="line.667"></a>
-<span class="sourceLineNo">668</span>     * @param chanceOfNoSwap Chance that this will decide to try a move rather<a name="line.668"></a>
-<span class="sourceLineNo">669</span>     *                       than a swap.<a name="line.669"></a>
-<span class="sourceLineNo">670</span>     * @return a random {@link RegionInfo} or null if an asymmetrical move is<a name="line.670"></a>
-<span class="sourceLineNo">671</span>     *         suggested.<a name="line.671"></a>
-<span class="sourceLineNo">672</span>     */<a name="line.672"></a>
-<span class="sourceLineNo">673</span>    protected int pickRandomRegion(Cluster cluster, int server, double chanceOfNoSwap) {<a name="line.673"></a>
-<span class="sourceLineNo">674</span>      // Check to see if this is just a move.<a name="line.674"></a>
-<span class="sourceLineNo">675</span>      if (cluster.regionsPerServer[server].length == 0 || RANDOM.nextFloat() &lt; chanceOfNoSwap) {<a name="line.675"></a>
-<span class="sourceLineNo">676</span>        // signal a move only.<a name="line.676"></a>
-<span class="sourceLineNo">677</span>        return -1;<a name="line.677"></a>
-<span class="sourceLineNo">678</span>      }<a name="line.678"></a>
-<span class="sourceLineNo">679</span>      int rand = RANDOM.nextInt(cluster.regionsPerServer[server].length);<a name="line.679"></a>
-<span class="sourceLineNo">680</span>      return cluster.regionsPerServer[server][rand];<a name="line.680"></a>
-<span class="sourceLineNo">681</span><a name="line.681"></a>
-<span class="sourceLineNo">682</span>    }<a name="line.682"></a>
-<span class="sourceLineNo">683</span>    protected int pickRandomServer(Cluster cluster) {<a name="line.683"></a>
-<span class="sourceLineNo">684</span>      if (cluster.numServers &lt; 1) {<a name="line.684"></a>
-<span class="sourceLineNo">685</span>        return -1;<a name="line.685"></a>
-<span class="sourceLineNo">686</span>      }<a name="line.686"></a>
-<span class="sourceLineNo">687</span><a name="line.687"></a>
-<span class="sourceLineNo">688</span>      return RANDOM.nextInt(cluster.numServers);<a name="line.688"></a>
-<span class="sourceLineNo">689</span>    }<a name="line.689"></a>
-<span class="sourceLineNo">690</span><a name="line.690"></a>
-<span class="sourceLineNo">691</span>    protected int pickRandomRack(Cluster cluster) {<a name="line.691"></a>
-<span class="sourceLineNo">692</span>      if (cluster.numRacks &lt; 1) {<a name="line.692"></a>
-<span class="sourceLineNo">693</span>        return -1;<a name="line.693"></a>
-<span class="sourceLineNo">694</span>      }<a name="line.694"></a>
-<span class="sourceLineNo">695</span><a name="line.695"></a>
-<span class="sourceLineNo">696</span>      return RANDOM.nextInt(cluster.numRacks);<a name="line.696"></a>
-<span class="sourceLineNo">697</span>    }<a name="line.697"></a>
-<span class="sourceLineNo">698</span><a name="line.698"></a>
-<span class="sourceLineNo">699</span>    protected int pickOtherRandomServer(Cluster cluster, int serverIndex) {<a name="line.699"></a>
-<span class="sourceLineNo">700</span>      if (cluster.numServers &lt; 2) {<a name="line.700"></a>
-<span class="sourceLineNo">701</span>        return -1;<a name="line.701"></a>
-<span class="sourceLineNo">702</span>      }<a name="line.702"></a>
-<span class="sourceLineNo">703</span>      while (true) {<a name="line.703"></a>
-<span class="sourceLineNo">704</span>        int otherServerIndex = pickRandomServer(cluster);<a name="line.704"></a>
-<span class="sourceLineNo">705</span>        if (otherServerIndex != serverIndex) {<a name="line.705"></a>
-<span class="sourceLineNo">706</span>          return otherServerIndex;<a name="line.706"></a>
-<span class="sourceLineNo">707</span>        }<a name="line.707"></a>
-<span class="sourceLineNo">708</span>      }<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>    protected int pickOtherRandomRack(Cluster cluster, int rackIndex) {<a name="line.711"></a>
-<span class="sourceLineNo">712</span>      if (cluster.numRacks &lt; 2) {<a name="line.712"></a>
-<span class="sourceLineNo">713</span>        return -1;<a name="line.713"></a>
-<span class="sourceLineNo">714</span>      }<a name="line.714"></a>
-<span class="sourceLineNo">715</span>      while (true) {<a name="line.715"></a>
-<span class="sourceLineNo">716</span>        int otherRackIndex = pickRandomRack(cluster);<a name="line.716"></a>
-<span class="sourceLineNo">717</span>        if (otherRackIndex != rackIndex) {<a name="line.717"></a>
-<span class="sourceLineNo">718</span>          return otherRackIndex;<a name="line.718"></a>
-<span class="sourceLineNo">719</span>        }<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>    protected Cluster.Action pickRandomRegions(Cluster cluster,<a name="line.723"></a>
-<span class="sourceLineNo">724</span>                                                       int thisServer,<a name="line.724"></a>
-<span class="sourceLineNo">725</span>                                                       int otherServer) {<a name="line.725"></a>
-<span class="sourceLineNo">726</span>      if (thisServer &lt; 0 || otherServer &lt; 0) {<a name="line.726"></a>
-<span class="sourceLineNo">727</span>        return Cluster.NullAction;<a name="line.727"></a>
-<span class="sourceLineNo">728</span>      }<a name="line.728"></a>
-<span class="sourceLineNo">729</span><a name="line.729"></a>
-<span class="sourceLineNo">730</span>      // Decide who is most likely to need another region<a name="line.730"></a>
-<span class="sourceLineNo">731</span>      int thisRegionCount = cluster.getNumRegions(thisServer);<a name="line.731"></a>
-<span class="sourceLineNo">732</span>      int otherRegionCount = cluster.getNumRegions(otherServer);<a name="line.732"></a>
-<span class="sourceLineNo">733</span><a name="line.733"></a>
-<span class="sourceLineNo">734</span>      // Assign the chance based upon the above<a name="line.734"></a>
-<span class="sourceLineNo">735</span>      double thisChance = (thisRegionCount &gt; otherRegionCount) ? 0 : 0.5;<a name="line.735"></a>
-<span class="sourceLineNo">736</span>      double otherChance = (thisRegionCount &lt;= otherRegionCount) ? 0 : 0.5;<a name="line.736"></a>
-<span class="sourceLineNo">737</span><a name="line.737"></a>
-<span class="sourceLineNo">738</span>      int thisRegion = pickRandomRegion(cluster, thisServer, thisChance);<a name="line.738"></a>
-<span class="sourceLineNo">739</span>      int otherRegion = pickRandomRegion(cluster, otherServer, otherChance);<a name="line.739"></a>
-<span class="sourceLineNo">740</span><a name="line.740"></a>
-<span class="sourceLineNo">741</span>      return getAction(thisServer, thisRegion, otherServer, otherRegion);<a name="line.741"></a>
-<span class="sourceLineNo">742</span>    }<a name="line.742"></a>
-<span class="sourceLineNo">743</span><a name="line.743"></a>
-<span class="sourceLineNo">744</span>    protected Cluster.Action getAction(int fromServer, int fromRegion,<a name="line.744"></a>
-<span class="sourceLineNo">745</span>        int toServer, int toRegion) {<a name="line.745"></a>
-<span class="sourceLineNo">746</span>      if (fromServer &lt; 0 || toServer &lt; 0) {<a name="line.746"></a>
-<span class="sourceLineNo">747</span>        return Cluster.NullAction;<a name="line.747"></a>
-<span class="sourceLineNo">748</span>      }<a name="line.748"></a>
-<span class="sourceLineNo">749</span>      if (fromRegion &gt; 0 &amp;&amp; toRegion &gt; 0) {<a name="line.749"></a>
-<span class="sourceLineNo">750</span>        return new Cluster.SwapRegionsAction(fromServer, fromRegion,<a name="line.750"></a>
-<span class="sourceLineNo">751</span>          toServer, toRegion);<a name="line.751"></a>
-<span class="sourceLineNo">752</span>      } else if (fromRegion &gt; 0) {<a name="line.752"></a>
-<span class="sourceLineNo">753</span>        return new Cluster.MoveRegionAction(fromRegion, fromServer, toServer);<a name="line.753"></a>
-<span class="sourceLineNo">754</span>      } else if (toRegion &gt; 0) {<a name="line.754"></a>
-<span class="sourceLineNo">755</span>        return new Cluster.MoveRegionAction(toRegion, toServer, fromServer);<a name="line.755"></a>
-<span class="sourceLineNo">756</span>      } else {<a name="line.756"></a>
-<span class="sourceLineNo">757</span>        return Cluster.NullAction;<a name="line.757"></a>
-<span class="sourceLineNo">758</span>      }<a name="line.758"></a>
-<span class="sourceLineNo">759</span>    }<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>     * Returns a random iteration order of indexes of an array with size length<a name="line.762"></a>
-<span class="sourceLineNo">763</span>     */<a name="line.763"></a>
-<span class="sourceLineNo">764</span>    protected List&lt;Integer&gt; getRandomIterationOrder(int length) {<a name="line.764"></a>
-<span class="sourceLineNo">765</span>      ArrayList&lt;Integer&gt; order = new ArrayList&lt;&gt;(length);<a name="line.765"></a>
-<span class="sourceLineNo">766</span>      for (int i = 0; i &lt; length; i++) {<a name="line.766"></a>
-<span class="sourceLineNo">767</span>        order.add(i);<a name="line.767"></a>
-<span class="sourceLineNo">768</span>      }<a name="line.768"></a>
-<span class="sourceLineNo">769</span>      Collections.shuffle(order);<a name="line.769"></a>
-<span class="sourceLineNo">770</span>      return order;<a name="line.770"></a>
-<span class="sourceLineNo">771</span>    }<a name="line.771"></a>
-<span class="sourceLineNo">772</span>  }<a name="line.772"></a>
-<span class="sourceLineNo">773</span><a name="line.773"></a>
-<span class="sourceLineNo">774</span>  static class RandomCandidateGenerator extends CandidateGenerator {<a name="line.774"></a>
+<span class="sourceLineNo">484</span>    metricsBalancer.balanceCluster(endTime - startTime);<a name="line.484"></a>
+<span class="sourceLineNo">485</span><a name="line.485"></a>
+<span class="sourceLineNo">486</span>    // update costs metrics<a name="line.486"></a>
+<span class="sourceLineNo">487</span>    updateStochasticCosts(tableName, curOverallCost, curFunctionCosts);<a name="line.487"></a>
+<span class="sourceLineNo">488</span>    if (initCost &gt; currentCost) {<a name="line.488"></a>
+<span class="sourceLineNo">489</span>      plans = createRegionPlans(cluster);<a name="line.489"></a>
+<span class="sourceLineNo">490</span>      LOG.info("Finished computing new load balance plan. Computation took {}" +<a name="line.490"></a>
+<span class="sourceLineNo">491</span>        " to try {} different iterations.  Found a solution that moves " +<a name="line.491"></a>
+<span class="sourceLineNo">492</span>        "{} regions; Going from a computed cost of {}" +<a name="line.492"></a>
+<span class="sourceLineNo">493</span>        " to a new cost of {}", java.time.Duration.ofMillis(endTime - startTime),<a name="line.493"></a>
+<span class="sourceLineNo">494</span>        step, plans.size(), initCost, currentCost);<a name="line.494"></a>
+<span class="sourceLineNo">495</span>      return plans;<a name="line.495"></a>
+<span class="sourceLineNo">496</span>    }<a name="line.496"></a>
+<span class="sourceLineNo">497</span>    LOG.info("Could not find a better load balance plan.  Tried {} different configurations in " +<a name="line.497"></a>
+<span class="sourceLineNo">498</span>      "{}, and did not find anything with a computed cost less than {}", step,<a name="line.498"></a>
+<span class="sourceLineNo">499</span>      java.time.Duration.ofMillis(endTime - startTime), initCost);<a name="line.499"></a>
+<span class="sourceLineNo">500</span>    return null;<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>  /**<a name="line.503"></a>
+<span class="sourceLineNo">504</span>   * update costs to JMX<a name="line.504"></a>
+<span class="sourceLineNo">505</span>   */<a name="line.505"></a>
+<span class="sourceLineNo">506</span>  private void updateStochasticCosts(TableName tableName, Double overall, Double[] subCosts) {<a name="line.506"></a>
+<span class="sourceLineNo">507</span>    if (tableName == null) return;<a name="line.507"></a>
+<span class="sourceLineNo">508</span><a name="line.508"></a>
+<span class="sourceLineNo">509</span>    // check if the metricsBalancer is MetricsStochasticBalancer before casting<a name="line.509"></a>
+<span class="sourceLineNo">510</span>    if (metricsBalancer instanceof MetricsStochasticBalancer) {<a name="line.510"></a>
+<span class="sourceLineNo">511</span>      MetricsStochasticBalancer balancer = (MetricsStochasticBalancer) metricsBalancer;<a name="line.511"></a>
+<span class="sourceLineNo">512</span>      // overall cost<a name="line.512"></a>
+<span class="sourceLineNo">513</span>      balancer.updateStochasticCost(tableName.getNameAsString(),<a name="line.513"></a>
+<span class="sourceLineNo">514</span>        "Overall", "Overall cost", overall);<a name="line.514"></a>
+<span class="sourceLineNo">515</span><a name="line.515"></a>
+<span class="sourceLineNo">516</span>      // each cost function<a name="line.516"></a>
+<span class="sourceLineNo">517</span>      for (int i = 0; i &lt; costFunctions.size(); i++) {<a name="line.517"></a>
+<span class="sourceLineNo">518</span>        CostFunction costFunction = costFunctions.get(i);<a name="line.518"></a>
+<span class="sourceLineNo">519</span>        String costFunctionName = costFunction.getClass().getSimpleName();<a name="line.519"></a>
+<span class="sourceLineNo">520</span>        Double costPercent = (overall == 0) ? 0 : (subCosts[i] / overall);<a name="line.520"></a>
+<span class="sourceLineNo">521</span>        // TODO: cost function may need a specific description<a name="line.521"></a>
+<span class="sourceLineNo">522</span>        balancer.updateStochasticCost(tableName.getNameAsString(), costFunctionName,<a name="line.522"></a>
+<span class="sourceLineNo">523</span>          "The percent of " + costFunctionName, costPercent);<a name="line.523"></a>
+<span class="sourceLineNo">524</span>      }<a name="line.524"></a>
+<span class="sourceLineNo">525</span>    }<a name="line.525"></a>
+<span class="sourceLineNo">526</span>  }<a name="line.526"></a>
+<span class="sourceLineNo">527</span><a name="line.527"></a>
+<span class="sourceLineNo">528</span>  private String functionCost() {<a name="line.528"></a>
+<span class="sourceLineNo">529</span>    StringBuilder builder = new StringBuilder();<a name="line.529"></a>
+<span class="sourceLineNo">530</span>    for (CostFunction c:costFunctions) {<a name="line.530"></a>
+<span class="sourceLineNo">531</span>      builder.append(c.getClass().getSimpleName());<a name="line.531"></a>
+<span class="sourceLineNo">532</span>      builder.append(" : (");<a name="line.532"></a>
+<span class="sourceLineNo">533</span>      builder.append(c.getMultiplier());<a name="line.533"></a>
+<span class="sourceLineNo">534</span>      builder.append(", ");<a name="line.534"></a>
+<span class="sourceLineNo">535</span>      builder.append(c.cost());<a name="line.535"></a>
+<span class="sourceLineNo">536</span>      builder.append("); ");<a name="line.536"></a>
+<span class="sourceLineNo">537</span>    }<a name="line.537"></a>
+<span class="sourceLineNo">538</span>    return builder.toString();<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>  /**<a name="line.541"></a>
+<span class="sourceLineNo">542</span>   * Create all of the RegionPlan's needed to move from the initial cluster state to the desired<a name="line.542"></a>
+<span class="sourceLineNo">543</span>   * state.<a name="line.543"></a>
+<span class="sourceLineNo">544</span>   *<a name="line.544"></a>
+<span class="sourceLineNo">545</span>   * @param cluster The state of the cluster<a name="line.545"></a>
+<span class="sourceLineNo">546</span>   * @return List of RegionPlan's that represent the moves needed to get to desired final state.<a name="line.546"></a>
+<span class="sourceLineNo">547</span>   */<a name="line.547"></a>
+<span class="sourceLineNo">548</span>  private List&lt;RegionPlan&gt; createRegionPlans(Cluster cluster) {<a name="line.548"></a>
+<span class="sourceLineNo">549</span>    List&lt;RegionPlan&gt; plans = new LinkedList&lt;&gt;();<a name="line.549"></a>
+<span class="sourceLineNo">550</span>    for (int regionIndex = 0;<a name="line.550"></a>
+<span class="sourceLineNo">551</span>         regionIndex &lt; cluster.regionIndexToServerIndex.length; regionIndex++) {<a name="line.551"></a>
+<span class="sourceLineNo">552</span>      int initialServerIndex = cluster.initialRegionIndexToServerIndex[regionIndex];<a name="line.552"></a>
+<span class="sourceLineNo">553</span>      int newServerIndex = cluster.regionIndexToServerIndex[regionIndex];<a name="line.553"></a>
+<span class="sourceLineNo">554</span><a name="line.554"></a>
+<span class="sourceLineNo">555</span>      if (initialServerIndex != newServerIndex) {<a name="line.555"></a>
+<span class="sourceLineNo">556</span>        RegionInfo region = cluster.regions[regionIndex];<a name="line.556"></a>
+<span class="sourceLineNo">557</span>        ServerName initialServer = cluster.servers[initialServerIndex];<a name="line.557"></a>
+<span class="sourceLineNo">558</span>        ServerName newServer = cluster.servers[newServerIndex];<a name="line.558"></a>
+<span class="sourceLineNo">559</span><a name="line.559"></a>
+<span class="sourceLineNo">560</span>        if (LOG.isTraceEnabled()) {<a name="line.560"></a>
+<span class="sourceLineNo">561</span>          LOG.trace("Moving Region " + region.getEncodedName() + " from server "<a name="line.561"></a>
+<span class="sourceLineNo">562</span>              + initialServer.getHostname() + " to " + newServer.getHostname());<a name="line.562"></a>
+<span class="sourceLineNo">563</span>        }<a name="line.563"></a>
+<span class="sourceLineNo">564</span>        RegionPlan rp = new RegionPlan(region, initialServer, newServer);<a name="line.564"></a>
+<span class="sourceLineNo">565</span>        plans.add(rp);<a name="line.565"></a>
+<span class="sourceLineNo">566</span>      }<a name="line.566"></a>
+<span class="sourceLineNo">567</span>    }<a name="line.567"></a>
+<span class="sourceLineNo">568</span>    return plans;<a name="line.568"></a>
+<span class="sourceLineNo">569</span>  }<a name="line.569"></a>
+<span class="sourceLineNo">570</span><a name="line.570"></a>
+<span class="sourceLineNo">571</span>  /**<a name="line.571"></a>
+<span class="sourceLineNo">572</span>   * Store the current region loads.<a name="line.572"></a>
+<span class="sourceLineNo">573</span>   */<a name="line.573"></a>
+<span class="sourceLineNo">574</span>  private synchronized void updateRegionLoad() {<a name="line.574"></a>
+<span class="sourceLineNo">575</span>    // We create a new hashmap so that regions that are no longer there are removed.<a name="line.575"></a>
+<span class="sourceLineNo">576</span>    // However we temporarily need the old loads so we can use them to keep the rolling average.<a name="line.576"></a>
+<span class="sourceLineNo">577</span>    Map&lt;String, Deque&lt;BalancerRegionLoad&gt;&gt; oldLoads = loads;<a name="line.577"></a>
+<span class="sourceLineNo">578</span>    loads = new HashMap&lt;&gt;();<a name="line.578"></a>
+<span class="sourceLineNo">579</span><a name="line.579"></a>
+<span class="sourceLineNo">580</span>    clusterStatus.getLiveServerMetrics().forEach((ServerName sn, ServerMetrics sm) -&gt; {<a name="line.580"></a>
+<span class="sourceLineNo">581</span>      sm.getRegionMetrics().forEach((byte[] regionName, RegionMetrics rm) -&gt; {<a name="line.581"></a>
+<span class="sourceLineNo">582</span>        String regionNameAsString = RegionInfo.getRegionNameAsString(regionName);<a name="line.582"></a>
+<span class="sourceLineNo">583</span>        Deque&lt;BalancerRegionLoad&gt; rLoads = oldLoads.get(regionNameAsString);<a name="line.583"></a>
+<span class="sourceLineNo">584</span>        if (rLoads == null) {<a name="line.584"></a>
+<span class="sourceLineNo">585</span>          rLoads = new ArrayDeque&lt;&gt;(numRegionLoadsToRemember + 1);<a name="line.585"></a>
+<span class="sourceLineNo">586</span>        } else if (rLoads.size() &gt;= numRegionLoadsToRemember) {<a name="line.586"></a>
+<span class="sourceLineNo">587</span>          rLoads.remove();<a name="line.587"></a>
+<span class="sourceLineNo">588</span>        }<a name="line.588"></a>
+<span class="sourceLineNo">589</span>        rLoads.add(new BalancerRegionLoad(rm));<a name="line.589"></a>
+<span class="sourceLineNo">590</span>        loads.put(regionNameAsString, rLoads);<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>    for(CostFromRegionLoadFunction cost : regionLoadFunctions) {<a name="line.594"></a>
+<span class="sourceLineNo">595</span>      cost.setLoads(loads);<a name="line.595"></a>
+<span class="sourceLineNo">596</span>    }<a name="line.596"></a>
+<span class="sourceLineNo">597</span>  }<a name="line.597"></a>
+<span class="sourceLineNo">598</span><a name="line.598"></a>
+<span class="sourceLineNo">599</span>  protected void initCosts(Cluster cluster) {<a name="line.599"></a>
+<span class="sourceLineNo">600</span>    for (CostFunction c:costFunctions) {<a name="line.600"></a>
+<span class="sourceLineNo">601</span>      c.init(cluster);<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><a name="line.604"></a>
+<span class="sourceLineNo">605</span>  protected void updateCostsWithAction(Cluster cluster, Action action) {<a name="line.605"></a>
+<span class="sourceLineNo">606</span>    for (CostFunction c : costFunctions) {<a name="line.606"></a>
+<span class="sourceLineNo">607</span>      c.postAction(action);<a name="line.607"></a>
+<span class="sourceLineNo">608</span>    }<a name="line.608"></a>
+<span class="sourceLineNo">609</span>  }<a name="line.609"></a>
+<span class="sourceLineNo">610</span><a name="line.610"></a>
+<span class="sourceLineNo">611</span>  /**<a name="line.611"></a>
+<span class="sourceLineNo">612</span>   * Get the names of the cost functions<a name="line.612"></a>
+<span class="sourceLineNo">613</span>   */<a name="line.613"></a>
+<span class="sourceLineNo">614</span>  public String[] getCostFunctionNames() {<a name="line.614"></a>
+<span class="sourceLineNo">615</span>    if (costFunctions == null) return null;<a name="line.615"></a>
+<span class="sourceLineNo">616</span>    String[] ret = new String[costFunctions.size()];<a name="line.616"></a>
+<span class="sourceLineNo">617</span>    for (int i = 0; i &lt; costFunctions.size(); i++) {<a name="line.617"></a>
+<span class="sourceLineNo">618</span>      CostFunction c = costFunctions.get(i);<a name="line.618"></a>
+<span class="sourceLineNo">619</span>      ret[i] = c.getClass().getSimpleName();<a name="line.619"></a>
+<span class="sourceLineNo">620</span>    }<a name="line.620"></a>
+<span class="sourceLineNo">621</span><a name="line.621"></a>
+<span class="sourceLineNo">622</span>    return ret;<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>  /**<a name="line.625"></a>
+<span class="sourceLineNo">626</span>   * This is the main cost function.  It will compute a cost associated with a proposed cluster<a name="line.626"></a>
+<span class="sourceLineNo">627</span>   * state.  All different costs will be combined with their multipliers to produce a double cost.<a name="line.627"></a>
+<span class="sourceLineNo">628</span>   *<a name="line.628"></a>
+<span class="sourceLineNo">629</span>   * @param cluster The state of the cluster<a name="line.629"></a>
+<span class="sourceLineNo">630</span>   * @param previousCost the previous cost. This is used as an early out.<a name="line.630"></a>
+<span class="sourceLineNo">631</span>   * @return a double of a cost associated with the proposed cluster state.  This cost is an<a name="line.631"></a>
+<span class="sourceLineNo">632</span>   *         aggregate of all individual cost functions.<a name="line.632"></a>
+<span class="sourceLineNo">633</span>   */<a name="line.633"></a>
+<span class="sourceLineNo">634</span>  protected double computeCost(Cluster cluster, double previousCost) {<a name="line.634"></a>
+<span class="sourceLineNo">635</span>    double total = 0;<a name="line.635"></a>
+<span class="sourceLineNo">636</span><a name="line.636"></a>
+<span class="sourceLineNo">637</span>    for (int i = 0; i &lt; costFunctions.size(); i++) {<a name="line.637"></a>
+<span class="sourceLineNo">638</span>      CostFunction c = costFunctions.get(i);<a name="line.638"></a>
+<span class="sourceLineNo">639</span>      this.tempFunctionCosts[i] = 0.0;<a name="line.639"></a>
+<span class="sourceLineNo">640</span><a name="line.640"></a>
+<span class="sourceLineNo">641</span>      if (c.getMultiplier() &lt;= 0) {<a name="line.641"></a>
+<span class="sourceLineNo">642</span>        continue;<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>      Float multiplier = c.getMultiplier();<a name="line.645"></a>
+<span class="sourceLineNo">646</span>      Double cost = c.cost();<a name="line.646"></a>
+<span class="sourceLineNo">647</span><a name="line.647"></a>
+<span class="sourceLineNo">648</span>      this.tempFunctionCosts[i] = multiplier*cost;<a name="line.648"></a>
+<span class="sourceLineNo">649</span>      total += this.tempFunctionCosts[i];<a name="line.649"></a>
+<span class="sourceLineNo">650</span><a name="line.650"></a>
+<span class="sourceLineNo">651</span>      if (total &gt; previousCost) {<a name="line.651"></a>
+<span class="sourceLineNo">652</span>        break;<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><a name="line.655"></a>
+<span class="sourceLineNo">656</span>    return total;<a name="line.656"></a>
+<span class="sourceLineNo">657</span>  }<a name="line.657"></a>
+<span class="sourceLineNo">658</span><a name="line.658"></a>
+<span class="sourceLineNo">659</span>  /** Generates a candidate action to be applied to the cluster for cost function search */<a name="line.659"></a>
+<span class="sourceLineNo">660</span>  abstract static class CandidateGenerator {<a name="line.660"></a>
+<span class="sourceLineNo">661</span>    abstract Cluster.Action generate(Cluster cluster);<a name="line.661"></a>
+<span class="sourceLineNo">662</span><a name="line.662"></a>
+<span class="sourceLineNo">663</span>    /**<a name="line.663"></a>
+<span class="sourceLineNo">664</span>     * From a list of regions pick a random one. Null can be returned which<a name="line.664"></a>
+<span class="sourceLineNo">665</span>     * {@link StochasticLoadBalancer#balanceCluster(Map)} recognize as signal to try a region move<a name="line.665"></a>
+<span class="sourceLineNo">666</span>     * rather than swap.<a name="line.666"></a>
+<span class="sourceLineNo">667</span>     *<a name="line.667"></a>
+<span class="sourceLineNo">668</span>     * @param cluster        The state of the cluster<a name="line.668"></a>
+<span class="sourceLineNo">669</span>     * @param server         index of the server<a name="line.669"></a>
+<span class="sourceLineNo">670</span>     * @param chanceOfNoSwap Chance that this will decide to try a move rather<a name="line.670"></a>
+<span class="sourceLineNo">671</span>     *                       than a swap.<a name="line.671"></a>
+<span class="sourceLineNo">672</span>     * @return a random {@link RegionInfo} or null if an asymmetrical move is<a name="line.672"></a>
+<span class="sourceLineNo">673</span>     *         suggested.<a name="line.673"></a>
+<span class="sourceLineNo">674</span>     */<a name="line.674"></a>
+<span class="sourceLineNo">675</span>    protected int pickRandomRegion(Cluster cluster, int server, double chanceOfNoSwap) {<a name="line.675"></a>
+<span class="sourceLineNo">676</span>      // Check to see if this is just a move.<a name="line.676"></a>
+<span class="sourceLineNo">677</span>      if (cluster.regionsPerServer[server].length == 0 || RANDOM.nextFloat() &lt; chanceOfNoSwap) {<a name="line.677"></a>
+<span class="sourceLineNo">678</span>        // signal a move only.<a name="line.678"></a>
+<span class="sourceLineNo">679</span>        return -1;<a name="line.679"></a>
+<span class="sourceLineNo">680</span>      }<a name="line.680"></a>
+<span class="sourceLineNo">681</span>      int rand = RANDOM.nextInt(cluster.regionsPerServer[server].length);<a name="line.681"></a>
+<span class="sourceLineNo">682</span>      return cluster.regionsPerServer[server][rand];<a name="line.682"></a>
+<span class="sourceLineNo">683</span><a name="line.683"></a>
+<span class="sourceLineNo">684</span>    }<a name="line.684"></a>
+<span class="sourceLineNo">685</span>    protected int pickRandomServer(Cluster cluster) {<a name="line.685"></a>
+<span class="sourceLineNo">686</span>      if (cluster.numServers &lt; 1) {<a name="line.686"></a>
+<span class="sourceLineNo">687</span>        return -1;<a name="line.687"></a>
+<span class="sourceLineNo">688</span>      }<a name="line.688"></a>
+<span class="sourceLineNo">689</span><a name="line.689"></a>
+<span class="sourceLineNo">690</span>      return RANDOM.nextInt(cluster.numServers);<a name="line.690"></a>
+<span class="sourceLineNo">691</span>    }<a name="line.691"></a>
+<span class="sourceLineNo">692</span><a name="line.692"></a>
+<span class="sourceLineNo">693</span>    protected int pickRandomRack(Cluster cluster) {<a name="line.693"></a>
+<span class="sourceLineNo">694</span>      if (cluster.numRacks &lt; 1) {<a name="line.694"></a>
+<span class="sourceLineNo">695</span>        return -1;<a name="line.695"></a>
+<span class="sourceLineNo">696</span>      }<a name="line.696"></a>
+<span class="sourceLineNo">697</span><a name="line.697"></a>
+<span class="sourceLineNo">698</span>      return RANDOM.nextInt(cluster.numRacks);<a name="line.698"></a>
+<span class="sourceLineNo">699</span>    }<a name="line.699"></a>
+<span class="sourceLineNo">700</span><a name="line.700"></a>
+<span class="sourceLineNo">701</span>    protected int pickOtherRandomServer(Cluster cluster, int serverIndex) {<a name="line.701"></a>
+<span class="sourceLineNo">702</span>      if (cluster.numServers &lt; 2) {<a name="line.702"></a>
+<span class="sourceLineNo">703</span>        return -1;<a name="line.703"></a>
+<span class="sourceLineNo">704</span>      }<a name="line.704"></a>
+<span class="sourceLineNo">705</span>      while (true) {<a name="line.705"></a>
+<span class="sourceLineNo">706</span>        int otherServerIndex = pickRandomServer(cluster);<a name="line.706"></a>
+<span class="sourceLineNo">707</span>        if (otherServerIndex != serverIndex) {<a name="line.707"></a>
+<span class="sourceLineNo">708</span>          return otherServerIndex;<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><a name="line.712"></a>
+<span class="sourceLineNo">713</span>    protected int pickOtherRandomRack(Cluster cluster, int rackIndex) {<a name="line.713"></a>
+<span class="sourceLineNo">714</span>      if (cluster.numRacks &lt; 2) {<a name="line.714"></a>
+<span class="sourceLineNo">715</span>        return -1;<a name="line.715"></a>
+<span class="sourceLineNo">716</span>      }<a name="line.716"></a>
+<span class="sourceLineNo">717</span>      while (true) {<a name="line.717"></a>
+<span class="sourceLineNo">718</span>        int otherRackIndex = pickRandomRack(cluster);<a name="line.718"></a>
+<span class="sourceLineNo">719</span>        if (otherRackIndex != rackIndex) {<a name="line.719"></a>
+<span class="sourceLineNo">720</span>          return otherRackIndex;<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><a name="line.724"></a>
+<span class="sourceLineNo">725</span>    protected Cluster.Action pickRandomRegions(Cluster cluster,<a name="line.725"></a>
+<span class="sourceLineNo">726</span>                                                       int thisServer,<a name="line.726"></a>
+<span class="sourceLineNo">727</span>                                                       int otherServer) {<a name="line.727"></a>
+<span class="sourceLineNo">728</span>      if (thisServer &lt; 0 || otherServer &lt; 0) {<a name="line.728"></a>
+<span class="sourceLineNo">729</span>        return Cluster.NullAction;<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>      // Decide who is most likely to need another region<a name="line.732"></a>
+<span class="sourceLineNo">733</span>      int thisRegionCount = cluster.getNumRegions(thisServer);<a name="line.733"></a>
+<span class="sourceLineNo">734</span>      int otherRegionCount = cluster.getNumRegions(otherServer);<a name="line.734"></a>
+<span class="sourceLineNo">735</span><a name="line.735"></a>
+<span class="sourceLineNo">736</span>      // Assign the chance based upon the above<a name="line.736"></a>
+<span class="sourceLineNo">737</span>      double thisChance = (thisRegionCount &gt; otherRegionCount) ? 0 : 0.5;<a name="line.737"></a>
+<span class="sourceLineNo">738</span>      double otherChance = (thisRegionCount &lt;= otherRegionCount) ? 0 : 0.5;<a name="line.738"></a>
+<span class="sourceLineNo">739</span><a name="line.739"></a>
+<span class="sourceLineNo">740</span>      int thisRegion = pickRandomRegion(cluster, thisServer, thisChance);<a name="line.740"></a>
+<span class="sourceLineNo">741</span>      int otherRegion = pickRandomRegion(cluster, otherServer, otherChance);<a name="line.741"></a>
+<span class="sourceLineNo">742</span><a name="line.742"></a>
+<span class="sourceLineNo">743</span>      return getAction(thisServer, thisRegion, otherServer, otherRegion);<a name="line.743"></a>
+<span class="sourceLineNo">744</span>    }<a name="line.744"></a>
+<span class="sourceLineNo">745</span><a name="line.745"></a>
+<span class="sourceLineNo">746</span>    protected Cluster.Action getAction(int fromServer, int fromRegion,<a name="line.746"></a>
+<span class="sourceLineNo">747</span>        int toServer, int toRegion) {<a name="line.747"></a>
+<span class="sourceLineNo">748</span>      if (fromServer &lt; 0 || toServer &lt; 0) {<a name="line.748"></a>
+<span class="sourceLineNo">749</span>        return Cluster.NullAction;<a name="line.749"></a>
+<span class="sourceLineNo">750</span>      }<a name="line.750"></a>
+<span class="sourceLineNo">751</span>      if (fromRegion &gt; 0 &amp;&amp; toRegion &gt; 0) {<a name="line.751"></a>
+<span class="sourceLineNo">752</span>        return new Cluster.SwapRegionsAction(fromServer, fromRegion,<a name="line.752"></a>
+<span class="sourceLineNo">753</span>          toServer, toRegion);<a name="line.753"></a>
+<span class="sourceLineNo">754</span>      } else if (fromRegion &gt; 0) {<a name="line.754"></a>
+<span class="sourceLineNo">755</span>        return new Cluster.MoveRegionAction(fromRegion, fromServer, toServer);<a name="line.755"></a>
+<span class="sourceLineNo">756</span>      } else if (toRegion &gt; 0) {<a name="line.756"></a>
+<span class="sourceLineNo">757</span>        return new Cluster.MoveRegionAction(toRegion, toServer, fromServer);<a name="line.757"></a>
+<span class="sourceLineNo">758</span>      } else {<a name="line.758"></a>
+<span class="sourceLineNo">759</span>        return Cluster.NullAction;<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><a name="line.762"></a>
+<span class="sourceLineNo">763</span>    /**<a name="line.763"></a>
+<span class="sourceLineNo">764</span>     * Returns a random iteration order of indexes of an array with size length<a name="line.764"></a>
+<span class="sourceLineNo">765</span>     */<a name="line.765"></a>
+<span class="sourceLineNo">766</span>    protected List&lt;Integer&gt; getRandomIterationOrder(int length) {<a name="line.766"></a>
+<span class="sourceLineNo">767</span>      ArrayList&lt;Integer&gt; order = new ArrayList&lt;&gt;(length);<a name="line.767"></a>
+<span class="sourceLineNo">768</span>      for (int i = 0; i &lt; length; i++) {<a name="line.768"></a>
+<span class="sourceLineNo">769</span>        order.add(i);<a name="line.769"></a>
+<span class="sourceLineNo">770</span>      }<a name="line.770"></a>
+<span class="sourceLineNo">771</span>      Collections.shuffle(order);<a name="line.771"></a>
+<span class="sourceLineNo">772</span>      return order;<a name="line.772"></a>
+<span class="sourceLineNo">773</span>    }<a name="line.773"></a>
+<span class="sourceLineNo">774</span>  }<a name="line.774"></a>
 <span class="sourceLineNo">775</span><a name="line.775"></a>
-<span class="sourceLineNo">776</span>    @Override<a name="line.776"></a>
-<span class="sourceLineNo">777</span>    Cluster.Action generate(Cluster cluster) {<a name="line.777"></a>
-<span class="sourceLineNo">778</span><a name="line.778"></a>
-<span class="sourceLineNo">779</span>      int thisServer = pickRandomServer(cluster);<a name="line.779"></a>
+<span class="sourceLineNo">776</span>  static class RandomCandidateGenerator extends CandidateGenerator {<a name="line.776"></a>
+<span class="sourceLineNo">777</span><a name="line.777"></a>
+<span class="sourceLineNo">778</span>    @Override<a name="line.778"></a>
+<span class="sourceLineNo">779</span>    Cluster.Action generate(Cluster cluster) {<a name="line.779"></a>
 <span class="sourceLineNo">780</span><a name="line.780"></a>
-<span class="sourceLineNo">781</span>      // Pick the other server<a name="line.781"></a>
-<span class="sourceLineNo">782</span>      int otherServer = pickOtherRandomServer(cluster, thisServer);<a name="line.782"></a>
-<span class="sourceLineNo">783</span><a name="line.783"></a>
-<span class="sourceLineNo">784</span>      return pickRandomRegions(cluster, thisServer, otherServer);<a name="line.784"></a>
-<span class="sourceLineNo">785</span>    }<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>  static class LoadCandidateGenerator extends CandidateGenerator {<a name="line.788"></a>
+<span class="sourceLineNo">781</span>      int thisServer = pickRandomServer(cluster);<a name="line.781"></a>
+<span class="sourceLineNo">782</span><a name="line.782"></a>
+<span class="sourceLineNo">783</span>      // Pick the other server<a name="line.783"></a>
+<span class="sourceLineNo">784</span>      int otherServer = pickOtherRandomServer(cluster, thisServer);<a name="line.784"></a>
+<span class="sourceLineNo">785</span><a name="line.785"></a>
+<span class="sourceLineNo">786</span>      return pickRandomRegions(cluster, thisServer, otherServer);<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><a name="line.789"></a>
-<span class="sourceLineNo">790</span>    @Override<a name="line.790"></a>
-<span class="sourceLineNo">791</span>    Cluster.Action generate(Cluster cluster) {<a name="line.791"></a>
-<span class="sourceLineNo">792</span>      cluster.sortServersByRegionCount();<a name="line.792"></a>
-<span class="sourceLineNo">793</span>      int thisServer = pickMostLoadedServer(cluster, -1);<a name="line.793"></a>
-<span class="sourceLineNo">794</span>      int otherServer = pickLeastLoadedServer(cluster, thisServer);<a name="line.794"></a>
-<span class="sourceLineNo">795</span><a name="line.795"></a>
-<span class="sourceLineNo">796</span>      return pickRandomRegions(cluster, thisServer, otherServer);<a name="line.796"></a>
-<span class="sourceLineNo">797</span>    }<a name="line.797"></a>
-<span class="sourceLineNo">798</span><a name="line.798"></a>
-<span class="sourceLineNo">799</span>    private int pickLeastLoadedServer(final Cluster cluster, int thisServer) {<a name="line.799"></a>
-<span class="sourceLineNo">800</span>      Integer[] servers = cluster.serverIndicesSortedByRegionCount;<a name="line.800"></a>
-<span class="sourceLineNo">801</span><a name="line.801"></a>
-<span class="sourceLineNo">802</span>      int index = 0;<a name="line.802"></a>
-<span class="sourceLineNo">803</span>      while (servers[index] == null || servers[index] == thisServer) {<a name="line.803"></a>
-<span class="sourceLineNo">804</span>        index++;<a name="line.804"></a>
-<span class="sourceLineNo">805</span>        if (index == servers.length) {<a name="line.805"></a>
-<span class="sourceLineNo">806</span>          return -1;<a name="line.806"></a>
-<span class="sourceLineNo">807</span>        }<a name="line.807"></a>
-<span class="sourceLineNo">808</span>      }<a name="line.808"></a>
-<span class="sourceLineNo">809</span>      return servers[index];<a name="line.809"></a>
-<span class="sourceLineNo">810</span>    }<a name="line.810"></a>
-<span class="sourceLineNo">811</span><a name="line.811"></a>
-<span class="sourceLineNo">812</span>    private int pickMostLoadedServer(final Cluster cluster, int thisServer) {<a name="line.812"></a>
-<span class="sourceLineNo">813</span>      Integer[] servers = cluster.serverIndicesSortedByRegionCount;<a name="line.813"></a>
-<span class="sourceLineNo">814</span><a name="line.814"></a>
-<span class="sourceLineNo">815</span>      int index = servers.length - 1;<a name="line.815"></a>
-<span class="sourceLineNo">816</span>      while (servers[index] == null || servers[index] == thisServer) {<a name="line.816"></a>
-<span class="sourceLineNo">817</span>        index--;<a name="line.817"></a>
-<span class="sourceLineNo">818</span>        if (index &lt; 0) {<a name="line.818"></a>
-<span class="sourceLineNo">819</span>          return -1;<a name="line.819"></a>
-<span class="sourceLineNo">820</span>        }<a name="line.820"></a>
-<span class="sourceLineNo">821</span>      }<a name="line.821"></a>
-<span class="sourceLineNo">822</span>      return servers[index];<a name="line.822"></a>
-<span class="sourceLineNo">823</span>    }<a name="line.823"></a>
-<span class="sourceLineNo">824</span>  }<a name="line.824"></a>
-<span class="sourceLineNo">825</span><a name="line.825"></a>
-<span class="sourceLineNo">826</span>  static class LocalityBasedCandidateGenerator extends CandidateGenerator {<a name="line.826"></a>
+<span class="sourceLineNo">790</span>  static class LoadCandidateGenerator extends CandidateGenerator {<a name="line.790"></a>
+<span class="sourceLineNo">791</span><a name="line.791"></a>
+<span class="sourceLineNo">792</span>    @Override<a name="line.792"></a>
+<span class="sourceLineNo">793</span>    Cluster.Action generate(Cluster cluster) {<a name="line.793"></a>
+<span class="sourceLineNo">794</span>      cluster.sortServersByRegionCount();<a name="line.794"></a>
+<span class="sourceLineNo">795</span>      int thisServer = pickMostLoadedServer(cluster, -1);<a name="line.795"></a>
+<span class="sourceLineNo">796</span>      int otherServer = pickLeastLoadedServer(cluster, thisServer);<a name="line.796"></a>
+<span class="sourceLineNo">797</span><a name="line.797"></a>
+<span class="sourceLineNo">798</span>      return pickRandomRegions(cluster, thisServer, otherServer);<a name="line.798"></a>
+<span class="sourceLineNo">799</span>    }<a name="line.799"></a>
+<span class="sourceLineNo">800</span><a name="line.800"></a>
+<span class="sourceLineNo">801</span>    private int pickLeastLoadedServer(final Cluster cluster, int thisServer) {<a name="line.801"></a>
+<span class="sourceLineNo">802</span>      Integer[] servers = cluster.serverIndicesSortedByRegionCount;<a name="line.802"></a>
+<span class="sourceLineNo">803</span><a name="line.803"></a>
+<span class="sourceLineNo">804</span>      int index = 0;<a name="line.804"></a>
+<span class="sourceLineNo">805</span>      while (servers[index] == null || servers[index] == thisServer) {<a name="line.805"></a>
+<span class="sourceLineNo">806</span>        index++;<a name="line.806"></a>
+<span class="sourceLineNo">807</span>        if (index == servers.length) {<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>      }<a name="line.810"></a>
+<span class="sourceLineNo">811</span>      return servers[index];<a name="line.811"></a>
+<span class="sourceLineNo">812</span>    }<a name="line.812"></a>
+<span class="sourceLineNo">813</span><a name="line.813"></a>
+<span class="sourceLineNo">814</span>    private int pickMostLoadedServer(final Cluster cluster, int thisServer) {<a name="line.814"></a>
+<span class="sourceLineNo">815</span>      Integer[] servers = cluster.serverIndicesSortedByRegionCount;<a name="line.815"></a>
+<span class="sourceLineNo">816</span><a name="line.816"></a>
+<span class="sourceLineNo">817</span>      int index = servers.length - 1;<a name="line.817"></a>
+<span class="sourceLineNo">818</span>      while (servers[index] == null || servers[index] == thisServer) {<a name="line.818"></a>
+<span class="sourceLineNo">819</span>        index--;<a name="line.819"></a>
+<span class="sourceLineNo">820</span>        if (index &lt; 0) {<a name="line.820"></a>
+<span class="sourceLineNo">821</span>          return -1;<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>      return servers[index];<a name="line.824"></a>
+<span class="sourceLineNo">825</span>    }<a name="line.825"></a>
+<span class="sourceLineNo">826</span>  }<a name="line.826"></a>
 <span class="sourceLineNo">827</span><a name="line.827"></a>
-<span class="sourceLineNo">828</span>    private MasterServices masterServices;<a name="line.828"></a>
+<span class="sourceLineNo">828</span>  static class LocalityBasedCandidateGenerator extends CandidateGenerator {<a name="line.828"></a>
 <span class="sourceLineNo">829</span><a name="line.829"></a>
-<span class="sourceLineNo">830</span>    LocalityBasedCandidateGenerator(MasterServices masterServices) {<a name="line.830"></a>
-<span class="sourceLineNo">831</span>      this.masterServices = masterServices;<a name="line.831"></a>
-<span class="sourceLineNo">832</span>    }<a name="line.832"></a>
-<span class="sourceLineNo">833</span><a name="line.833"></a>
-<span class="sourceLineNo">834</span>    @Override<a name="line.834"></a>
-<span class="sourceLineNo">835</span>    Cluster.Action generate(Cluster cluster) {<a name="line.835"></a>
-<span class="sourceLineNo">836</span>      if (this.masterServices == null) {<a name="line.836"></a>
-<span class="sourceLineNo">837</span>        int thisServer = pickRandomServer(cluster);<a name="line.837"></a>
-<span class="sourceLineNo">838</span>        // Pick the other server<a name="line.838"></a>
-<span class="sourceLineNo">839</span>        int otherServer = pickOtherRandomServer(cluster, thisServer);<a name="line.839"></a>
-<span class="sourceLineNo">840</span>        return pickRandomRegions(cluster, thisServer, otherServer);<a name="line.840"></a>
-<span class="sourceLineNo">841</span>      }<a name="line.841"></a>
-<span class="sourceLineNo">842</span><a name="line.842"></a>
-<span class="sourceLineNo">843</span>      // Randomly iterate through regions until you find one that is not on ideal host<a name="line.843"></a>
-<span class="sourceLineNo">844</span>      for (int region : getRandomIterationOrder(cluster.numRegions)) {<a name="line.844"></a>
-<span class="sourceLineNo">845</span>        int currentServer = cluster.regionIndexToServerIndex[region];<a name="line.845"></a>
-<span class="sourceLineNo">846</span>        if (currentServer != cluster.getOrComputeRegionsToMostLocalEntities(LocalityType.SERVER)[region]) {<a name="line.846"></a>
-<span class="sourceLineNo">847</span>          Optional&lt;Action&gt; potential = tryMoveOrSwap(<a name="line.847"></a>
-<span class="sourceLineNo">848</span>              cluster,<a name="line.848"></a>
-<span class="sourceLineNo">849</span>              currentServer,<a name="line.849"></a>
-<span class="sourceLineNo">850</span>              region,<a name="line.850"></a>
-<span class="sourceLineNo">851</span>              cluster.getOrComputeRegionsToMostLocalEntities(LocalityType.SERVER)[region]<a name="line.851"></a>
-<span class="sourceLineNo">852</span>          );<a name="line.852"></a>
-<span class="sourceLineNo">853</span>          if (potential.isPresent()) {<a name="line.853"></a>
-<span class="sourceLineNo">854</span>            return potential.get();<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>      }<a name="line.857"></a>
-<span class="sourceLineNo">858</span>      return Cluster.NullAction;<a name="line.858"></a>
-<span class="sourceLineNo">859</span>    }<a name="line.859"></a>
-<span class="sourceLineNo">860</span><a name="line.860"></a>
-<span class="sourceLineNo">861</span>    /**<a name="line.861"></a>
-<span class="sourceLineNo">862</span>     * Try to generate a move/swap fromRegion between fromServer and toServer such that locality is improved.<a name="line.862"></a>
-<span class="sourceLineNo">863</span>     * Returns empty optional if no move can be found<a name="line.863"></a>
-<span class="sourceLineNo">864</span>     */<a name="line.864"></a>
-<span class="sourceLineNo">865</span>    private Optional&lt;Action&gt; tryMoveOrSwap(Cluster cluster,<a name="line.865"></a>
-<span class="sourceLineNo">866</span>                                           int fromServer,<a name="line.866"></a>
-<span class="sourceLineNo">867</span>                                           int fromRegion,<a name="line.867"></a>
-<span class="sourceLineNo">868</span>                                           int toServer) {<a name="line.868"></a>
-<span class="sourceLineNo">869</span>      // Try move first. We know apriori fromRegion has the highest locality on toServer<a name="line.869"></a>
-<span class="sourceLineNo">870</span>      if (cluster.serverHasTooFewRegions(toServer)) {<a name="line.870"></a>
-<span class="sourceLineNo">871</span>        return Optional.of(getAction(fromServer, fromRegion, toServer, -1));<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>      // Compare locality gain/loss from swapping fromRegion with regions on toServer<a name="line.874"></a>
-<span class="sourceLineNo">875</span>      double fromRegionLocalityDelta =<a name="line.875"></a>
-<span class="sourceLineNo">876</span>          getWeightedLocality(cluster, fromRegion, toServer) - getWeightedLocality(cluster, fromRegion, fromServer);<a name="line.876"></a>
-<span class="sourceLineNo">877</span>      for (int toRegionIndex : getRandomIterationOrder(cluster.regionsPerServer[toServer].length)) {<a name="line.877"></a>
-<span class="sourceLineNo">878</span>        int toRegion = cluster.regionsPerServer[toServer][toRegionIndex];<a name="line.878"></a>
-<span class="sourceLineNo">879</span>        double toRegionLocalityDelta =<a name="line.879"></a>
-<span class="sourceLineNo">880</span>            getWeightedLocality(cluster, toRegion, fromServer) - getWeightedLocality(cluster, toRegion, toServer);<a name="line.880"></a>
-<span class="sourceLineNo">881</span>        // If locality would remain neutral or improve, attempt the swap<a name="line.881"></a>
-<span class="sourceLineNo">882</span>        if (fromRegionLocalityDelta + toRegionLocalityDelta &gt;= 0) {<a name="line.882"></a>
-<span class="sourceLineNo">883</span>          return Optional.of(getAction(fromServer, fromRegion, toServer, toRegion));<a name="line.883"></a>
-<span class="sourceLineNo">884</span>        }<a name="line.884"></a>
-<span class="sourceLineNo">885</span>      }<a name="line.885"></a>
-<span class="sourceLineNo">886</span><a name="line.886"></a>
-<span class="sourceLineNo">887</span>      return Optional.absent();<a name="line.887"></a>
-<span class="sourceLineNo">888</span>    }<a name="line.888"></a>
-<span class="sourceLineNo">889</span><a name="line.889"></a>
-<span class="sourceLineNo">890</span>    private double getWeightedLocality(Cluster cluster, int region, int server) {<a name="line.890"></a>
-<span class="sourceLineNo">891</span>      return cluster.getOrComputeWeightedLocality(region, server, LocalityType.SERVER);<a name="line.891"></a>
-<span class="sourceLineNo">892</span>    }<a name="line.892"></a>
-<span class="sourceLineNo">893</span><a name="line.893"></a>
-<span class="sourceLineNo">894</span>    void setServices(MasterServices services) {<a name="line.894"></a>
-<span class="sourceLineNo">895</span>      this.masterServices = services;<a name="line.895"></a>
-<span class="sourceLineNo">896</span>    }<a name="line.896"></a>
-<span class="sourceLineNo">897</span>  }<a name="line.897"></a>
-<span class="sourceLineNo">898</span><a name="line.898"></a>
-<span class="sourceLineNo">899</span>  /**<a name="line.899"></a>
-<span class="sourceLineNo">900</span>   * Generates candidates which moves the replicas out of the region server for<a name="line.900"></a>
-<span class="sourceLineNo">901</span>   * co-hosted region replicas<a name="line.901"></a>
-<span class="sourceLineNo">902</span>   */<a name="line.902"></a>
-<span class="sourceLineNo">903</span>  static class RegionReplicaCandidateGenerator extends CandidateGenerator {<a name="line.903"></a>
-<span class="sourceLineNo">904</span><a name="line.904"></a>
-<span class="sourceLineNo">905</span>    RandomCandidateGenerator randomGenerator = new RandomCandidateGenerator();<a name="line.905"></a>
+<span class="sourceLineNo">830</span>    private MasterServices masterServices;<a name="line.830"></a>
+<span class="sourceLineNo">831</span><a name="line.831"></a>
+<span class="sourceLineNo">832</span>    LocalityBasedCandidateGenerator(MasterServices masterServices) {<a name="line.832"></a>
+<span class="sourceLineNo">833</span>      this.masterServices = masterServices;<a name="line.833"></a>
+<span class="sourceLineNo">834</span>    }<a name="line.834"></a>
+<span class="sourceLineNo">835</span><a name="line.835"></a>
+<span class="sourceLineNo">836</span>    @Override<a name="line.836"></a>
+<span class="sourceLineNo">837</span>    Cluster.Action generate(Cluster cluster) {<a name="line.837"></a>
+<span class="sourceLineNo">838</span>      if (this.masterServices == null) {<a name="line.838"></a>
+<span class="sourceLineNo">839</span>        int thisServer = pickRandomServer(cluster);<a name="line.839"></a>
+<span class="sourceLineNo">840</span>        // Pick the other server<a name="line.840"></a>
+<span class="sourceLineNo">841</span>        int otherServer = pickOtherRandomServer(cluster, thisServer);<a name="line.841"></a>
+<span class="sourceLineNo">842</span>        return pickRandomRegions(cluster, thisServer, otherServer);<a name="line.842"></a>
+<span class="sourceLineNo">843</span>      }<a name="line.843"></a>
+<span class="sourceLineNo">844</span><a name="line.844"></a>
+<span class="sourceLineNo">845</span>      // Randomly iterate through regions until you find one that is not on ideal host<a name="line.845"></a>
+<span class="sourceLineNo">846</span>      for (int region : getRandomIterationOrder(cluster.numRegions)) {<a name="line.846"></a>
+<span class="sourceLineNo">847</span>        int currentServer = cluster.regionIndexToServerIndex[region];<a name="line.847"></a>
+<span class="sourceLineNo">848</span>        if (currentServer != cluster.getOrComputeRegionsToMostLocalEntities(LocalityType.SERVER)[region]) {<a name="line.848"></a>
+<span class="sourceLineNo">849</span>          Optional&lt;Action&gt; potential = tryMoveOrSwap(<a name="line.849"></a>
+<span class="sourceLineNo">850</span>              cluster,<a name="line.850"></a>
+<span class="sourceLineNo">851</span>              currentServer,<a name="line.851"></a>
+<span class="sourceLineNo">852</span>              region,<a name="line.852"></a>
+<span class="sourceLineNo">853</span>              cluster.getOrComputeRegionsToMostLocalEntities(LocalityType.SERVER)[region]<a name="line.853"></a>
+<span class="sourceLineNo">854</span>          );<a name="line.854"></a>
+<span class="sourceLineNo">855</span>          if (potential.isPresent()) {<a name="line.855"></a>
+<span class="sourceLineNo">856</span>            return potential.get();<a name="line.856"></a>
+<span class="sourceLineNo">857</span>          }<a name="line.857"></a>
+<span class="sourceLineNo">858</span>        }<a name="line.858"></a>
+<span class="sourceLineNo">859</span>      }<a name="line.859"></a>
+<span class="sourceLineNo">860</span>      return Cluster.NullAction;<a name="line.860"></a>
+<span class="sourceLineNo">861</span>    }<a name="line.861"></a>
+<span class="sourceLineNo">862</span><a name="line.862"></a>
+<span class="sourceLineNo">863</span>    /**<a name="line.863"></a>
+<span class="sourceLineNo">864</span>     * Try to generate a move/swap fromRegion between fromServer and toServer such that locality is improved.<a name="line.864"></a>
+<span class="sourceLineNo">865</span>     * Returns empty optional if no move can be found<a name="line.865"></a>
+<span class="sourceLineNo">866</span>     */<a name="line.866"></a>
+<span class="sourceLineNo">867</span>    private Optional&lt;Action&gt; tryMoveOrSwap(Cluster cluster,<a name="line.867"></a>
+<span class="sourceLineNo">868</span>                                           int fromServer,<a name="line.868"></a>
+<span class="sourceLineNo">869</span>                                           int fromRegion,<a name="line.869"></a>
+<span class="sourceLineNo">870</span>                                           int toServer) {<a name="line.870"></a>
+<span class="sourceLineNo">871</span>      // Try move first. We know apriori fromRegion has the highest locality on toServer<a name="line.871"></a>
+<span class="sourceLineNo">872</span>      if (cluster.serverHasTooFewRegions(toServer)) {<a name="line.872"></a>
+<span class="sourceLineNo">873</span>        return Optional.of(getAction(fromServer, fromRegion, toServer, -1));<a name="line.873"></a>
+<span class="sourceLineNo">874</span>      }<a name="line.874"></a>
+<span class="sourceLineNo">875</span><a name="line.875"></a>
+<span class="sourceLineNo">876</span>      // Compare locality gain/loss from swapping fromRegion with regions on toServer<a name="line.876"></a>
+<span class="sourceLineNo">877</span>      double fromRegionLocalityDelta =<a name="line.877"></a>
+<span class="sourceLineNo">878</span>          getWeightedLocality(cluster, fromRegion, toServer) - getWeightedLocality(cluster, fromRegion, fromServer);<a name="line.878"></a>
+<span class="sourceLineNo">879</span>      for (int toRegionIndex : getRandomIterationOrder(cluster.regionsPerServer[toServer].length)) {<a name="line.879"></a>
+<span class="sourceLineNo">880</span>        int toRegion = cluster.regionsPerServer[toServer][toRegionIndex];<a name="line.880"></a>
+<span class="sourceLineNo">881</span>        double toRegionLocalityDelta =<a name="line.881"></a>
+<span class="sourceLineNo">882</span>            getWeightedLocality(cluster, toRegion, fromServer) - getWeightedLocality(cluster, toRegion, toServer);<a name="line.882"></a>
+<span class="sourceLineNo">883</span>        // If locality would remain neutral or improve, attempt the swap<a name="line.883"></a>
+<span class="sourceLineNo">884</span>        if (fromRegionLocalityDelta + toRegionLocalityDelta &gt;= 0) {<a name="line.884"></a>
+<span class="sourceLineNo">885</span>          return Optional.of(getAction(fromServer, fromRegion, toServer, toRegion));<a name="line.885"></a>
+<span class="sourceLineNo">886</span>        }<a name="line.886"></a>
+<span class="sourceLineNo">887</span>      }<a name="line.887"></a>
+<span class="sourceLineNo">888</span><a name="line.888"></a>
+<span class="sourceLineNo">889</span>      return Optional.absent();<a name="line.889"></a>
+<span class="sourceLineNo">890</span>    }<a name="line.890"></a>
+<span class="sourceLineNo">891</span><a name="line.891"></a>
+<span class="sourceLineNo">892</span>    private double getWeightedLocality(Cluster cluster, int region, int server) {<a name="line.892"></a>
+<span class="sourceLineNo">893</span>      return cluster.getOrComputeWeightedLocality(region, server, LocalityType.SERVER);<a name="line.893"></a>
+<span class="sourceLineNo">894</span>    }<a name="line.894"></a>
+<span class="sourceLineNo">895</span><a name="line.895"></a>
+<span class="sourceLineNo">896</span>    void setServices(MasterServices services) {<a name="line.896"></a>
+<span class="sourceLineNo">897</span>      this.masterServices = services;<a name="line.897"></a>
+<span class="sourceLineNo">898</span>    }<a name="line.898"></a>
+<span class="sourceLineNo">899</span>  }<a name="line.899"></a>
+<span class="sourceLineNo">900</span><a name="line.900"></a>
+<span class="sourceLineNo">901</span>  /**<a name="line.901"></a>
+<span class="sourceLineNo">902</span>   * Generates candidates which moves the replicas out of the region server for<a name="line.902"></a>
+<span class="sourceLineNo">903</span>   * co-hosted region replicas<a name="line.903"></a>
+<span class="sourceLineNo">904</span>   */<a name="line.904"></a>
+<span class="sourceLineNo">905</span>  static class RegionReplicaCandidateGenerator extends CandidateGenerator {<a name="line.905"></a>
 <span class="sourceLineNo">906</span><a name="line.906"></a>
-<span class="sourceLineNo">907</span>    /**<a name="line.907"></a>
-<span class="sourceLineNo">908</span>     * Randomly select one regionIndex out of all region replicas co-hosted in the same group<a name="line.908"></a>
-<span class="sourceLineNo">909</span>     * (a group is a server, host or rack)<a name="line.909"></a>
-<span class="sourceLineNo">910</span>     * @param primariesOfRegionsPerGroup either Cluster.primariesOfRegionsPerServer,<a name="line.910"></a>
-<span class="sourceLineNo">911</span>     * primariesOfRegionsPerHost or primariesOfRegionsPerRack<a name="line.911"></a>
-<span class="sourceLineNo">912</span>     * @param regionsPerGroup either Cluster.regionsPerServer, regionsPerHost or regionsPerRack<a name="line.912"></a>
-<span class="sourceLineNo">913</span>     * @param regionIndexToPrimaryIndex Cluster.regionsIndexToPrimaryIndex<a name="line.913"></a>
-<span class="sourceLineNo">914</span>     * @return a regionIndex for the selected primary or -1 if there is no co-locating<a name="line.914"></a>
-<span class="sourceLineNo">915</span>     */<a name="line.915"></a>
-<span class="sourceLineNo">916</span>    int selectCoHostedRegionPerGroup(int[] primariesOfRegionsPerGroup, int[] regionsPerGroup<a name="line.916"></a>
-<span class="sourceLineNo">917</span>        , int[] regionIndexToPrimaryIndex) {<a name="line.917"></a>
-<span class="sourceLineNo">918</span>      int currentPrimary = -1;<a name="line.918"></a>
-<span class="sourceLineNo">919</span>      int currentPrimaryIndex = -1;<a name="line.919"></a>
-<span class="sourceLineNo">920</span>      int selectedPrimaryIndex = -1;<a name="line.920"></a>
-<span class="sourceLineNo">921</span>      double currentLargestRandom = -1;<a name="line.921"></a>
-<span class="sourceLineNo">922</span>      // primariesOfRegionsPerGroup is a sorted array. Since it contains the primary region<a name="line.922"></a>
-<span class="sourceLineNo">923</span>      // ids for the regions hosted in server, a consecutive repetition means that replicas<a name="line.923"></a>
-<span class="sourceLineNo">924</span>      // are co-hosted<a name="line.924"></a>
-<span class="sourceLineNo">925</span>      for (int j = 0; j &lt;= primariesOfRegionsPerGroup.length; j++) {<a name="line.925"></a>
-<span class="sourceLineNo">926</span>        int primary = j &lt; primariesOfRegionsPerGroup.length<a name="line.926"></a>
-<span class="sourceLineNo">927</span>            ? primariesOfRegionsPerGroup[j] : -1;<a name="line.927"></a>
-<span class="sourceLineNo">928</span>        if (primary != currentPrimary) { // check for whether we see a new primary<a name="line.928"></a>
-<span class="sourceLineNo">929</span>          int numReplicas = j - currentPrimaryIndex;<a name="line.929"></a>
-<span class="sourceLineNo">930</span>          if (numReplicas &gt; 1) { // means consecutive primaries, indicating co-location<a name="line.930"></a>
-<span class="sourceLineNo">931</span>            // decide to select this primary region id or not<a name="line.931"></a>
-<span class="sourceLineNo">932</span>            double currentRandom = RANDOM.nextDouble();<a name="line.932"></a>
-<span class="sourceLineNo">933</span>            // we don't know how many region replicas are co-hosted, we will randomly select one<a name="line.933"></a>
-<span class="sourceLineNo">934</span>            // using reservoir sampling (http://gregable.com/2007/10/reservoir-sampling.html)<a name="line.934"></a>
-<span class="sourceLineNo">935</span>            if (currentRandom &gt; currentLargestRandom) {<a name="line.935"></a>
-<span class="sourceLineNo">936</span>              selectedPrimaryIndex = currentPrimary;<a name="line.936"></a>
-<span class="sourceLineNo">937</span>              currentLargestRandom = currentRandom;<a name="line.937"></a>
-<span class="sourceLineNo">938</span>            }<a name="line.938"></a>
-<span class="sourceLineNo">939</span>          }<a name="line.939"></a>
-<span class="sourceLineNo">940</span>          currentPrimary = primary;<a name="line.940"></a>
-<span class="sourceLineNo">941</span>          currentPrimaryIndex = j;<a name="line.941"></a>
-<span class="sourceLineNo">942</span>        }<a name="line.942"></a>
-<span class="sourceLineNo">943</span>      }<a name="line.943"></a>
-<span class="sourceLineNo">944</span><a name="line.944"></a>
-<span class="sourceLineNo">945</span>      // we have found the primary id for the region to move. Now find the actual regionIndex<a name="line.945"></a>
-<span class="sourceLineNo">946</span>      // with the given primary, prefer to move the secondary region.<a name="line.946"></a>
-<span class="sourceLineNo">947</span>      for (int j = 0; j &lt; regionsPerGroup.length; j++) {<a name="line.947"></a>
-<span class="sourceLineNo">948</span>        int regionIndex = regionsPerGroup[j];<a name="line.948"></a>
-<span class="sourceLineNo">949</span>        if (selectedPrimaryIndex == regionIndexToPrimaryIndex[regionIndex]) {<a name="line.949"></a>
-<span class="sourceLineNo">950</span>          // always move the secondary, not the primary<a name="line.950"></a>
-<span class="sourceLineNo">951</span>          if (selectedPrimaryIndex != regionIndex) {<a name="line.951"></a>
-<span class="sourceLineNo">952</span>            return regionIndex;<a name="line.952"></a>
-<span class="sourceLineNo">953</span>          }<a name="line.953"></a>
-<span class="sourceLineNo">954</span>        }<a name="line.954"></a>
-<span class="sourceLineNo">955</span>      }<a name="line.955"></a>
-<span class="sourceLineNo">956</span>      return -1;<a name="line.956"></a>
-<span class="sourceLineNo">957</span>    }<a name="line.957"></a>
-<span class="sourceLineNo">958</span><a name="line.958"></a>
-<span class="sourceLineNo">959</span>    @Override<a name="line.959"></a>
-<span class="sourceLineNo">960</span>    Cluster.Action generate(Cluster cluster) {<a name="line.960"></a>
-<span class="sourceLineNo">961</span>      int serverIndex = pickRandomServer(cluster);<a name="line.961"></a>
-<span class="sourceLineNo">962</span>      if (cluster.numServers &lt;= 1 || serverIndex == -1) {<a name="line.962"></a>
-<span class="sourceLineNo">963</span>        return Cluster.NullAction;<a name="line.963"></a>
-<span class="sourceLineNo">964</span>      }<a name="line.964"></a>
-<span class="sourceLineNo">965</span><a name="line.965"></a>
-<span class="sourceLineNo">966</span>      int regionIndex = selectCoHostedRegionPerGroup(<a name="line.966"></a>
-<span class="sourceLineNo">967</span>        cluster.primariesOfRegionsPerServer[serverIndex],<a name="line.967"></a>
-<span class="sourceLineNo">968</span>        cluster.regionsPerServer[serverIndex],<a name="line.968"></a>
-<span class="sourceLineNo">969</span>        cluster.regionIndexToPrimaryIndex);<a name="line.969"></a>
-<span class="sourceLineNo">970</span><a name="line.970"></a>
-<span class="sourceLineNo">971</span>      // if there are no pairs of region replicas co-hosted, default to random generator<a name="line.971"></a>
-<span class="sourceLineNo">972</span>      if (regionIndex == -1) {<a name="line.972"></a>
-<span class="sourceLineNo">973</span>        // default to randompicker<a name="line.973"></a>
-<span class="sourceLineNo">974</span>        return randomGenerator.generate(cluster);<a name="line.974"></a>
-<span class="sourceLineNo">975</span>      }<a name="line.975"></a>
-<span class="sourceLineNo">976</span><a name="line.976"></a>
-<span class="sourceLineNo">977</span>      int toServerIndex = pickOtherRandomServer(cluster, serverIndex);<a name="line.977"></a>
-<span class="sourceLineNo">978</span>      int toRegionIndex = pickRandomRegion(cluster, toServerIndex, 0.9f);<a name="line.978"></a>
-<span class="sourceLineNo">979</span>      return getAction(serverIndex, regionIndex, toServerIndex, toRegionIndex);<a name="line.979"></a>
-<span class="sourceLineNo">980</span>    }<a name="line.980"></a>
-<span class="sourceLineNo">981</span>  }<a name="line.981"></a>
-<span class="sourceLineNo">982</span><a name="line.982"></a>
-<span class="sourceLineNo">983</span>  /**<a name="line.983"></a>
-<span class="sourceLineNo">984</span>   * Generates candidates which moves the replicas out of the rack for<a name="line.984"></a>
-<span class="sourceLineNo">985</span>   * co-hosted region replicas in the same rack<a name="line.985"></a>
-<span class="sourceLineNo">986</span>   */<a name="line.986"></a>
-<span class="sourceLineNo">987</span>  static class RegionReplicaRackCandidateGenerator extends RegionReplicaCandidateGenerator {<a name="line.987"></a>
-<span class="sourceLineNo">988</span>    @Override<a name="line.988"></a>
-<span class="sourceLineNo">989</span>    Cluster.Action generate(Cluster cluster) {<a name="line.989"></a>
-<span class="sourceLineNo">990</span>      int rackIndex = pickRandomRack(cluster);<a name="line.990"></a>
-<span class="sourceLineNo">991</span>      if (cluster.numRacks &lt;= 1 || rackIndex == -1) {<a name="line.991"></a>
-<span class="sourceLineNo">992</span>        return super.generate(cluster);<a name="line.992"></a>
-<span class="sourceLineNo">993</span>      }<a name="line.993"></a>
-<span class="sourceLineNo">994</span><a name="line.994"></a>
-<span class="sourceLineNo">995</span>      int regionIndex = selectCoHostedRegionPerGroup(<a name="line.995"></a>
-<span class="sourceLineNo">996</span>        cluster.primariesOfRegionsPerRack[rackIndex],<a name="line.996"></a>
-<span class="sourceLineNo">997</span>        cluster.regionsPerRack[rackIndex],<a name="line.997"></a>
-<span class="sourceLineNo">998</span>        cluster.regionIndexToPrimaryIndex);<a name="line.998"></a>
-<span class="sourceLineNo">999</span><a name="line.999"></a>
-<span class="sourceLineNo">1000</span>      // if there are no pairs of region replicas co-hosted, default to random generator<a name="line.1000"></a>
-<span class="sourceLineNo">1001</span>      if (regionIndex == -1) {<a name="line.1001"></a>
-<span class="sourceLineNo">1002</span>        // default to randompicker<a name="line.1002"></a>
-<span class="sourceLineNo">1003</span>        return randomGenerator.generate(cluster);<a name="line.1003"></a>
-<span class="sourceLineNo">1004</span>      }<a name="line.1004"></a>
-<span class="sourceLineNo">1005</span><a name="line.1005"></a>
-<span class="sourceLineNo">1006</span>      int serverIndex = cluster.regionIndexToServerIndex[regionIndex];<a name="line.1006"></a>
-<span class="sourceLineNo">1007</span>      int toRackIndex = pickOtherRandomRack(cluster, rackIndex);<a name="line.1007"></a>
-<span class="sourceLineNo">1008</span><a name="line.1008"></a>
-<span class="sourceLineNo">1009</span>      int rand = RANDOM.nextInt(cluster.serversPerRack[toRackIndex].length);<a name="line.1009"></a>
-<span class="sourceLineNo">1010</span>      int toServerIndex = cluster.serversPerRack[toRackIndex][rand];<a name="line.1010"></a>
-<span class="sourceLineNo">1011</span>      int toRegionIndex = pickRandomRegion(cluster, toServerIndex, 0.9f);<a name="line.1011"></a>
-<span class="sourceLineNo">1012</span>      return getAction(serverIndex, regionIndex, toServerIndex, toRegionIndex);<a name="line.1012"></a>
-<span class="sourceLineNo">1013</span>    }<a name="line.1013"></a>
-<span class="sourceLineNo">1014</span>  }<a name="line.1014"></a>
-<span class="sourceLineNo">1015</span><a name="line.1015"></a>
-<span class="sourceLineNo">1016</span>  /**<a name="line.1016"></a>
-<span class="sourceLineNo">1017</span>   * Base class of StochasticLoadBalancer's Cost Functions.<a name="line.1017"></a>
-<span class="sourceLineNo">1018</span>   */<a name="line.1018"></a>
-<span class="sourceLineNo">1019</span>  public abstract static class CostFunction {<a name="line.1019"></a>
-<span class="sourceLineNo">1020</span><a name="line.1020"></a>
-<span class="sourceLineNo">1021</span>    private float multiplier = 0;<a name="line.1021"></a>
+<span class="sourceLineNo">907</span>    RandomCandidateGenerator randomGenerator = new RandomCandidateGenerator();<a name="line.907"></a>
+<span class="sourceLineNo">908</span><a name="line.908"></a>
+<span class="sourceLineNo">909</span>    /**<a name="line.909"></a>
+<span class="sourceLineNo">910</span>     * Randomly select one regionIndex out of all region replicas co-hosted in the same group<a name="line.910"></a>
+<span class="sourceLineNo">911</span>     * (a group is a server, host or rack)<a name="line.911"></a>
+<span class="sourceLineNo">912</span>     * @param primariesOfRegionsPerGroup either Cluster.primariesOfRegionsPerServer,<a name="line.912"></a>
+<span class="sourceLineNo">913</span>     * primariesOfRegionsPerHost or primariesOfRegionsPerRack<a name="line.913"></a>
+<span class="sourceLineNo">914</span>     * @param regionsPerGroup either Cluster.regionsPerServer, regionsPerHost or regionsPerRack<a name="line.914"></a>
+<span class="sourceLineNo">915</span>     * @param regionIndexToPrimaryIndex Cluster.regionsIndexToPrimaryIndex<a name="line.915"></a>
+<span class="sourceLineNo">916</span>     * @return a regionIndex for the selected primary or -1 if there is no co-locating<a name="line.916"></a>
+<span class="sourceLineNo">917</span>     */<a name="line.917"></a>
+<span class="sourceLineNo">918</span>    int selectCoHostedRegionPerGroup(int[] primariesOfRegionsPerGroup, int[] regionsPerGroup<a name="line.918"></a>
+<span class="sourceLineNo">919</span>        , int[] regionIndexToPrimaryIndex) {<a name="line.919"></a>
+<span class="sourceLineNo">920</span>      int currentPrimary = -1;<a name="line.920"></a>
+<span class="sourceLineNo">921</span>      int currentPrimaryIndex = -1;<a name="line.921"></a>
+<span class="sourceLineNo">922</span>      int selectedPrimaryIndex = -1;<a name="line.922"></a>
+<span class="sourceLineNo">923</span>      double currentLargestRandom = -1;<a name="line.923"></a>
+<span class="sourceLineNo">924</span>      // primariesOfRegionsPerGroup is a sorted array. Since it contains the primary region<a name="line.924"></a>
+<span class="sourceLineNo">925</span>      // ids for the regions hosted in server, a consecutive repetition means that replicas<a name="line.925"></a>
+<span class="sourceLineNo">926</span>      // are co-hosted<a name="line.926"></a>
+<span class="sourceLineNo">927</span>      for (int j = 0; j &lt;= primariesOfRegionsPerGroup.length; j++) {<a name="line.927"></a>
+<span class="sourceLineNo">928</span>        int primary = j &lt; primariesOfRegionsPerGroup.length<a name="line.928"></a>
+<span class="sourceLineNo">929</span>            ? primariesOfRegionsPerGroup[j] : -1;<a name="line.929"></a>
+<span class="sourceLineNo">930</span>        if (primary != currentPrimary) { // check for whether we see a new primary<a name="line.930"></a>
+<span class="sourceLineNo">931</span>          int numReplicas = j - currentPrimaryIndex;<a name="line.931"></a>
+<span class="sourceLineNo">932</span>          if (numReplicas &gt; 1) { // means consecutive primaries, indicating co-location<a name="line.932"></a>
+<span class="sourceLineNo">933</span>            // decide to select this primary region id or not<a name="line.933"></a>
+<span class="sourceLineNo">934</span>            double currentRandom = RANDOM.nextDouble();<a name="line.934"></a>
+<span class="sourceLineNo">935</span>            // we don't know how many region replicas are co-hosted, we will randomly select one<a name="line.935"></a>
+<span class="sourceLineNo">936</span>            // using reservoir sampling (http://gregable.com/2007/10/reservoir-sampling.html)<a name="line.936"></a>
+<span class="sourceLineNo">937</span>            if (currentRandom &gt; currentLargestRandom) {<a name="line.937"></a>
+<span class="sourceLineNo">938</span>              selectedPrimaryIndex = currentPrimary;<a name="line.938"></a>
+<span class="sourceLineNo">939</span>              currentLargestRandom = currentRandom;<a name="line.939"></a>
+<span class="sourceLineNo">940</span>            }<a name="line.940"></a>
+<span class="sourceLineNo">941</span>          }<a name="line.941"></a>
+<span class="sourceLineNo">942</span>          currentPrimary = primary;<a name="line.942"></a>
+<span class="sourceLineNo">943</span>          currentPrimaryIndex = j;<a name="line.943"></a>
+<span class="sourceLineNo">944</span>        }<a name="line.944"></a>
+<span class="sourceLineNo">945</span>      }<a name="line.945"></a>
+<span class="sourceLineNo">946</span><a name="line.946"></a>
+<span class="sourceLineNo">947</span>      // we have found the primary id for the region to move. Now find the actual regionIndex<a name="line.947"></a>
+<span class="sourceLineNo">948</span>      // with the given primary, prefer to move the secondary region.<a name="line.948"></a>
+<span class="sourceLineNo">949</span>      for (int j = 0; j &lt; regionsPerGroup.length; j++) {<a name="line.949"></a>
+<span class="sourceLineNo">950</span>        int regionIndex = regionsPerGroup[j];<a name="line.950"></a>
+<span class="sourceLineNo">951</span>        if (selectedPrimaryIndex == regionIndexToPrimaryIndex[regionIndex]) {<a name="line.951"></a>
+<span class="sourceLineNo">952</span>          // always move the secondary, not the primary<a name="line.952"></a>
+<span class="sourceLineNo">953</span>          if (selectedPrimaryIndex != regionIndex) {<a name="line.953"></a>
+<span class="sourceLineNo">954</span>            return regionIndex;<a name="line.954"></a>
+<span class="sourceLineNo">955</span>          }<a name="line.955"></a>
+<span class="sourceLineNo">956</span>        }<a name="line.956"></a>
+<span class="sourceLineNo">957</span>      }<a name="line.957"></a>
+<span class="sourceLineNo">958</span>      return -1;<a name="line.958"></a>
+<span class="sourceLineNo">959</span>    }<a name="line.959"></a>
+<span class="sourceLineNo">960</span><a name="line.960"></a>
+<span class="sourceLineNo">961</span>    @Override<a name="line.961"></a>
+<span class="sourceLineNo">962</span>    Cluster.Action generate(Cluster cluster) {<a name="line.962"></a>
+<span class="sourceLineNo">963</span>      int serverIndex = pickRandomServer(cluster);<a name="line.963"></a>
+<span class="sourceLineNo">964</span>      if (cluster.numServers &lt;= 1 || serverIndex == -1) {<a name="line.964"></a>
+<span class="sourceLineNo">965</span>        return Cluster.NullAction;<a name="line.965"></a>
+<span class="sourceLineNo">966</span>      }<a name="line.966"></a>
+<span class="sourceLineNo">967</span><a name="line.967"></a>
+<span class="sourceLineNo">968</span>      int regionIndex = selectCoHostedRegionPerGroup(<a name="line.968"></a>
+<span class="sourceLineNo">969</span>        cluster.primariesOfRegionsPerServer[serverIndex],<a name="line.969"></a>
+<span class="sourceLineNo">970</span>        cluster.regionsPerServer[serverIndex],<a name="line.970"></a>
+<span class="sourceLineNo">971</span>        cluster.regionIndexToPrimaryIndex);<a name="line.971"></a>
+<span class="sourceLineNo">972</span><a name="line.972"></a>
+<span class="sourceLineNo">973</span>      // if there are no pairs of region replicas co-hosted, default to random generator<a name="line.973"></a>
+<span class="sourceLineNo">974</span>      if (regionIndex == -1) {<a name="line.974"></a>
+<span class="sourceLineNo">975</span>        // default to randompicker<a name="line.975"></a>
+<span class="sourceLineNo">976</span>        return randomGenerator.generate(cluster);<a name="line.976"></a>
+<span class="sourceLineNo">977</span>      }<a name="line.977"></a>
+<span class="sourceLineNo">978</span><a name="line.978"></a>
+<span class="sourceLineNo">979</span>      int toServerIndex = pickOtherRandomServer(cluster, serverIndex);<a name="line.979"></a>
+<span class="sourceLineNo">980</span>      int toRegionIndex = pickRandomRegion(cluster, toServerIndex, 0.9f);<a name="line.980"></a>
+<span class="sourceLineNo">981</span>      return getAction(serverIndex, regionIndex, toServerIndex, toRegionIndex);<a name="line.981"></a>
+<span class="sourceLineNo">982</span>    }<a name="line.982"></a>
+<span class="sourceLineNo">983</span>  }<a name="line.983"></a>
+<span class="sourceLineNo">984</span><a name="line.984"></a>
+<span class="sourceLineNo">985</span>  /**<a name="line.985"></a>
+<span class="sourceLineNo">986</span>   * Generates candidates which moves the replicas out of the rack for<a name="line.986"></a>
+<span class="sourceLineNo">987</span>   * co-hosted region replicas in the same rack<a name="line.987"></a>
+<span class="sourceLineNo">988</span>   */<a name="line.988"></a>
+<span class="sourceLineNo">989</span>  static class RegionReplicaRackCandidateGenerator extends RegionReplicaCandidateGenerator {<a name="line.989"></a>
+<span class="sourceLineNo">990</span>    @Override<a name="line.990"></a>
+<span class="sourceLineNo">991</span>    Cluster.Action generate(Cluster cluster) {<a name="line.991"></a>
+<span class="sourceLineNo">992</span>      int rackIndex = pickRandomRack(cluster);<a name="line.992"></a>
+<span class="sourceLineNo">993</span>      if (cluster.numRacks &lt;= 1 || rackIndex == -1) {<a name="line.993"></a>
+<span class="sourceLineNo">994</span>        return super.generate(cluster);<a name="line.994"></a>
+<span class="sourceLineNo">995</span>      }<a name="line.995"></a>
+<span class="sourceLineNo">996</span><a name="line.996"></a>
+<span class="sourceLineNo">997</span>      int regionIndex = selectCoHostedRegionPerGroup(<a name="line.997"></a>
+<span class="sourceLineNo">998</span>        cluster.primariesOfRegionsPerRack[rackIndex],<a name="line.998"></a>
+<span class="sourceLineNo">999</span>        cluster.regionsPerRack[rackIndex],<a name="line.999"></a>
+<span class="sourceLineNo">1000</span>        cluster.regionIndexToPrimaryIndex);<a name="line.1000"></a>
+<span class="sourceLineNo">1001</span><a name="line.1001"></a>
+<span class="sourceLineNo">1002</span>      // if there are no pairs of region replicas co-hosted, default to random generator<a name="line.1002"></a>
+<span class="sourceLineNo">1003</span>      if (regionIndex == -1) {<a name="line.1003"></a>
+<span class="sourceLineNo">1004</span>        // default to randompicker<a name="line.1004"></a>
+<span class="sourceLineNo">1005</span>        return randomGenerator.generate(cluster);<a name="line.1005"></a>
+<span class="sourceLineNo">1006</span>      }<a name="line.1006"></a>
+<span class="sourceLineNo">1007</span><a name="line.1007"></a>
+<span class="sourceLineNo">1008</span>      int serverIndex = cluster.regionIndexToServerIndex[regionIndex];<a name="line.1008"></a>
+<span class="sourceLineNo">1009</span>      int toRackIndex = pickOtherRandomRack(cluster, rackIndex);<a name="line.1009"></a>
+<span class="sourceLineNo">1010</span><a name="line.1010"></a>
+<span class="sourceLineNo">1011</span>      int rand = RANDOM.nextInt(cluster.serversPerRack[toRackIndex].length);<a name="line.1011"></a>
+<span class="sourceLineNo">1012</span>      int toServerIndex = cluster.serversPerRack[toRackIndex][rand];<a name="line.1012"></a>
+<span class="sourceLineNo">1013</span>      int toRegionIndex = pickRandomRegion(cluster, toServerIndex, 0.9f);<a name="line.1013"></a>
+<span class="sourceLineNo">1014</span>      return getAction(serverIndex, regionIndex, toServerIndex, toRegionIndex);<a name="line.1014"></a>
+<span class="sourceLineNo">1015</span>    }<a name="line.1015"></a>
+<span class="sourceLineNo">1016</span>  }<a name="line.1016"></a>
+<span class="sourceLineNo">1017</span><a name="line.1017"></a>
+<span class="sourceLineNo">1018</span>  /**<a name="line.1018"></a>
+<span class="sourceLineNo">1019</span>   * Base class of StochasticLoadBalancer's Cost Functions.<a name="line.1019"></a>
+<span class="sourceLineNo">1020</span>   */<a name="line.1020"></a>
+<span class="sourceLineNo">1021</span>  public abstract static class CostFunction {<a name="line.1021"></a>
 <span class="sourceLineNo">1022</span><a name="line.1022"></a>
-<span class="sourceLineNo">1023</span>    protected Cluster cluster;<a name="line.1023"></a>
+<span class="sourceLineNo">1023</span>    private float multiplier = 0;<a name="line.1023"></a>
 <span class="sourceLineNo">1024</span><a name="line.1024"></a>
-<span class="sourceLineNo">1025</span>    public CostFunction(Configuration c) {<a name="line.1025"></a>
-<span class="sourceLineNo">1026</span>    }<a name="line.1026"></a>
-<span class="sourceLineNo">1027</span><a name="line.1027"></a>
-<span class="sourceLineNo">1028</span>    boolean isNeeded() {<a name="line.1028"></a>
-<span class="sourceLineNo">1029</span>      return true;<a name="line.1029"></a>
-<span class="sourceLineNo">1030</span>    }<a name="line.1030"></a>
-<span class="sourceLineNo">1031</span>    float getMultiplier() {<a name="line.1031"></a>
-<span class="sourceLineNo">1032</span>      return multiplier;<a name="line.1032"></a>
-<span class="sourceLineNo">1033</span>    }<a name="line.1033"></a>
-<span class="sourceLineNo">1034</span><a name="line.1034"></a>
-<span class="sourceLineNo">1035</span>    void setMultiplier(float m) {<a name="line.1035"></a>
-<span class="sourceLineNo">1036</span>      this.multiplier = m;<a name="line.1036"></a>
-<span class="sourceLineNo">1037</span>    }<a name="line.1037"></a>
-<span class="sourceLineNo">1038</span><a name="line.1038"></a>
-<span class="sourceLineNo">1039</span>    /** Called once per LB invocation to give the cost function<a name="line.1039"></a>
-<span class="sourceLineNo">1040</span>     * to initialize it's state, and perform any costly calculation.<a name="line.1040"></a>
-<span class="sourceLineNo">1041</span>     */<a name="line.1041"></a>
-<span class="sourceLineNo">1042</span>    void init(Cluster cluster) {<a name="line.1042"></a>
-<span class="sourceLineNo">1043</span>      this.cluster = cluster;<a name="line.1043"></a>
-<span class="sourceLineNo">1044</span>    }<a name="line.1044"></a>
-<span class="sourceLineNo">1045</span><a name="line.1045"></a>
-<span class="sourceLineNo">1046</span>    /** Called once per cluster Action to give the cost function<a name="line.1046"></a>
-<span class="sourceLineNo">1047</span>     * an opportunity to update it's state. postAction() is always<a name="line.1047"></a>
-<span class="sourceLineNo">1048</span>     * called at least once before cost() is called with the cluster<a name="line.1048"></a>
-<span class="sourceLineNo">1049</span>     * that this action is performed on. */<a name="line.1049"></a>
-<span class="sourceLineNo">1050</span>    void postAction(Action action) {<a name="line.1050"></a>
-<span class="sourceLineNo">1051</span>      switch (action.type) {<a name="line.1051"></a>
-<span class="sourceLineNo">1052</span>      case NULL: break;<a name="line.1052"></a>
-<span class="sourceLineNo">1053</span>      case ASSIGN_REGION:<a name="line.1053"></a>
-<span class="sourceLineNo">1054</span>        AssignRegionAction ar = (AssignRegionAction) action;<a name="line.1054"></a>
-<span class="sourceLineNo">1055</span>        regionMoved(ar.region, -1, ar.server);<a name="line.1055"></a>
-<span class="sourceLineNo">1056</span>        break;<a name="line.1056"></a>
-<span class="sourceLineNo">1057</span>      case MOVE_REGION:<a name="line.1057"></a>
-<span class="sourceLineNo">1058</span>        MoveRegionAction mra = (MoveRegionAction) action;<a name="line.1058"></a>
-<span class="sourceLineNo">1059</span>        regionMoved(mra.region, mra.fromServer, mra.toServer);<a name="line.1059"></a>
-<span class="sourceLineNo">1060</span>        break;<a name="line.1060"></a>
-<span class="sourceLineNo">1061</span>      case SWAP_REGIONS:<a name="line.1061"></a>
-<span class="sourceLineNo">1062</span>        SwapRegionsAction a = (SwapRegionsAction) action;<a name="line.1062"></a>
-<span class="sourceLineNo">1063</span>        regionMoved(a.fromRegion, a.fromServer, a.toServer);<a name="line.1063"></a>
-<span class="sourceLineNo">1064</span>        regionMoved(a.toRegion, a.toServer, a.fromServer);<a name="line.1064"></a>
-<span class="sourceLineNo">1065</span>        break;<a name="line.1065"></a>
-<span class="sourceLineNo">1066</span>      default:<a name="line.1066"></a>
-<span class="sourceLineNo">1067</span>        throw new RuntimeException("Uknown action:" + action.type);<a name="line.1067"></a>
-<span class="sourceLineNo">1068</span>      }<a name="line.1068"></a>
-<span class="sourceLineNo">1069</span>    }<a name="line.1069"></a>
-<span class="sourceLineNo">1070</span><a name="line.1070"></a>
-<span class="sourceLineNo">1071</span>    protected void regionMoved(int region, int oldServer, int newServer) {<a name="line.1071"></a>
-<span class="sourceLineNo">1072</span>    }<a name="line.1072"></a>
-<span class="sourceLineNo">1073</span><a name="line.1073"></a>
-<span class="sourceLineNo">1074</span>    protected abstract double cost();<a name="line.1074"></a>
+<span class="sourceLineNo">1025</span>    protected Cluster cluster;<a name="line.1025"></a>
+<span class="sourceLineNo">1026</span><a name="line.1026"></a>
+<span class="sourceLineNo">1027</span>    public CostFunction(Configuration c) {<a name="line.1027"></a>
+<span class="sourceLineNo">1028</span>    }<a name="line.1028"></a>
+<span class="sourceLineNo">1029</span><a name="line.1029"></a>
+<span class="sourceLineNo">1030</span>    boolean isNeeded() {<a name="line.1030"></a>
+<span class="sourceLineNo">1031</span>      return true;<a name="line.1031"></a>
+<span class="sourceLineNo">1032</span>    }<a name="line.1032"></a>
+<span class="sourceLineNo">1033</span>    float getMultiplier() {<a name="line.1033"></a>
+<span class="sourceLineNo">1034</span>      return multiplier;<a name="line.1034"></a>
+<span class="sourceLineNo">1035</span>    }<a name="line.1035"></a>
+<span class="sourceLineNo">1036</span><a name="line.1036"></a>
+<span class="sourceLineNo">1037</span>    void setMultiplier(float m) {<a name="line.1037"></a>
+<span class="sourceLineNo">1038</span>      this.multiplier = m;<a name="line.1038"></a>
+<span class="sourceLineNo">1039</span>    }<a name="line.1039"></a>
+<span class="sourceLineNo">1040</span><a name="line.1040"></a>
+<span class="sourceLineNo">1041</span>    /** Called once per LB invocation to give the cost function<a name="line.1041"></a>
+<span class="sourceLineNo">1042</span>     * to initialize it's state, and perform any costly calculation.<a name="line.1042"></a>
+<span class="sourceLineNo">1043</span>     */<a name="line.1043"></a>
+<span class="sourceLineNo">1044</span>    void init(Cluster cluster) {<a name="line.1044"></a>
+<span class="sourceLineNo">1045</span>      this.cluster = cluster;<a name="line.1045"></a>
+<span class="sourceLineNo">1046</span>    }<a name="line.1046"></a>
+<span class="sourceLineNo">1047</span><a name="line.1047"></a>
+<span class="sourceLineNo">1048</span>    /** Called once per cluster Action to give the cost function<a name="line.1048"></a>
+<span class="sourceLineNo">1049</span>     * an opportunity to update it's state. postAction() is always<a name="line.1049"></a>
+<span class="sourceLineNo">1050</span>     * called at least once before cost() is called with the cluster<a name="line.1050"></a>
+<span class="sourceLineNo">1051</span>     * that this action is performed on. */<a name="line.1051"></a>
+<span class="sourceLineNo">1052</span>    void postAction(Action action) {<a name="line.1052"></a>
+<span class="sourceLineNo">1053</span>      switch (action.type) {<a name="line.1053"></a>
+<span class="sourceLineNo">1054</span>      case NULL: break;<a name="line.1054"></a>
+<span class="sourceLineNo">1055</span>      case ASSIGN_REGION:<a name="line.1055"></a>
+<span class="sourceLineNo">1056</span>        AssignRegionAction ar = (AssignRegionAction) action;<a name="line.1056"></a>
+<span class="sourceLineNo">1057</span>        regionMoved(ar.region, -1, ar.server);<a name="line.1057"></a>
+<span class="sourceLineNo">1058</span>        break;<a name="line.1058"></a>
+<span class="sourceLineNo">1059</span>      case MOVE_REGION:<a name="line.1059"></a>
+<span class="sourceLineNo">1060</span>        MoveRegionAction mra = (MoveRegionAction) action;<a name="line.1060"></a>
+<span class="sourceLineNo">1061</span>        regionMoved(mra.region, mra.fromServer, mra.toServer);<a name="line.1061"></a>
+<span class="sourceLineNo">1062</span>        break;<a name="line.1062"></a>
+<span class="sourceLineNo">1063</span>      case SWAP_REGIONS:<a name="line.1063"></a>
+<span class="sourceLineNo">1064</span>        SwapRegionsAction a = (SwapRegionsAction) action;<a name="line.1064"></a>
+<span class="sourceLineNo">1065</span>        regionMoved(a.fromRegion, a.fromServer, a.toServer);<a name="line.1065"></a>
+<span class="sourceLineNo">1066</span>        regionMoved(a.toRegion, a.toServer, a.fromServer);<a name="line.1066"></a>
+<span class="sourceLineNo">1067</span>        break;<a name="line.1067"></a>
+<span class="sourceLineNo">1068</span>      default:<a name="line.1068"></a>
+<span class="sourceLineNo">1069</span>        throw new RuntimeException("Uknown action:" + action.type);<a name="line.1069"></a>
+<span class="sourceLineNo">1070</span>      }<a name="line.1070"></a>
+<span class="sourceLineNo">1071</span>    }<a name="line.1071"></a>
+<span class="sourceLineNo">1072</span><a name="line.1072"></a>
+<span class="sourceLineNo">1073</span>    protected void regionMoved(int region, int oldServer, int newServer) {<a name="line.1073"></a>
+<span class="sourceLineNo">1074</span>    }<a name="line.1074"></a>
 <span class="sourceLineNo">1075</span><a name="line.1075"></a>
-<span class="sourceLineNo">1076</span>    @SuppressWarnings("checkstyle:linelength")<a name="line.1076"></a>
-<span class="sourceLineNo">1077</span>    /**<a name="line.1077"></a>
-<span class="sourceLineNo">1078</span>     * Function to compute a scaled cost using<a name="line.1078"></a>
-<span class="sourceLineNo">1079</span>     * {@link org.apache.commons.math3.stat.descriptive.DescriptiveStatistics#DescriptiveStatistics()}.<a name="line.1079"></a>
-<span class="sourceLineNo">1080</span>     * It assumes that this is a zero sum set of costs.  It assumes that the worst case<a name="line.1080"></a>
-<span class="sourceLineNo">1081</span>     * possible is all of the elements in one region server and the rest having 0.<a name="line.1081"></a>
-<span class="sourceLineNo">1082</span>     *<a name="line.1082"></a>
-<span class="sourceLineNo">1083</span>     * @param stats the costs<a name="line.1083"></a>
-<span class="sourceLineNo">1084</span>     * @return a scaled set of costs.<a name="line.1084"></a>
-<span class="sourceLineNo">1085</span>     */<a name="line.1085"></a>
-<span class="sourceLineNo">1086</span>    protected double costFromArray(double[] stats) {<a name="line.1086"></a>
-<span class="sourceLineNo">1087</span>      double totalCost = 0;<a name="line.1087"></a>
-<span class="sourceLineNo">1088</span>      double total = getSum(stats);<a name="line.1088"></a>
-<span class="sourceLineNo">1089</span><a name="line.1089"></a>
-<span class="sourceLineNo">1090</span>      double count = stats.length;<a name="line.1090"></a>
-<span class="sourceLineNo">1091</span>      double mean = total/count;<a name="line.1091"></a>
-<span class="sourceLineNo">1092</span><a name="line.1092"></a>
-<span class="sourceLineNo">1093</span>      // Compute max as if all region servers had 0 and one had the sum of all costs.  This must be<a name="line.1093"></a>
-<span class="sourceLineNo">1094</span>      // a zero sum cost for this to make sense.<a name="line.1094"></a>
-<span class="sourceLineNo">1095</span>      double max = ((count - 1) * mean) + (total - mean);<a name="line.1095"></a>
-<span class="sourceLineNo">1096</span><a name="line.1096"></a>
-<span class="sourceLineNo">1097</span>      // It's possible that there aren't enough regions to go around<a name="line.1097"></a>
-<span class="sourceLineNo">1098</span>      double min;<a name="line.1098"></a>
-<span class="sourceLineNo">1099</span>      if (count &gt; total) {<a name="line.1099"></a>
-<span class="sourceLineNo">1100</span>        min = ((count - total) * mean) + ((1 - mean) * total);<a name="line.1100"></a>
-<span class="sourceLineNo">1101</span>      } else {<a name="line.1101"></a>
-<span class="sourceLineNo">1102</span>        // Some will have 1 more than everything else.<a name="line.1102"></a>
-<span class="sourceLineNo">1103</span>        int numHigh = (int) (total - (Math.floor(mean) * count));<a name="line.1103"></a>
-<span class="sourceLineNo">1104</span>        int numLow = (int) (count - numHigh);<a name="line.1104"></a>
-<span class="sourceLineNo">1105</span><a name="line.1105"></a>
-<span class="sourceLineNo">1106</span>        min = (numHigh * (Math.ceil(mean) - mean)) + (numLow * (mean - Math.floor(mean)));<a name="line.1106"></a>
+<span class="sourceLineNo">1076</span>    protected abstract double cost();<a name="line.1076"></a>
+<span class="sourceLineNo">1077</span><a name="line.1077"></a>
+<span class="sourceLineNo">1078</span>    @SuppressWarnings("checkstyle:linelength")<a name="line.1078"></a>
+<span class="sourceLineNo">1079</span>    /**<a name="line.1079"></a>
+<span class="sourceLineNo">1080</span>     * Function to compute a scaled cost using<a name="line.1080"></a>
+<span class="sourceLineNo">1081</span>     * {@link org.apache.commons.math3.stat.descriptive.DescriptiveStatistics#DescriptiveStatistics()}.<a name="line.1081"></a>
+<span class="sourceLineNo">1082</span>     * It assumes that this is a zero sum set of costs.  It assumes that the worst case<a name="line.1082"></a>
+<span class="sourceLineNo">1083</span>     * possible is all of the elements in one region server and the rest having 0.<a name="line.1083"></a>
+<span class="sourceLineNo">1084</span>     *<a name="line.1084"></a>
+<span class="sourceLineNo">1085</span>     * @param stats the costs<a name="line.1085"></a>
+<span class="sourceLineNo">1086</span>     * @return a scaled set of costs.<a name="line.1086"></a>
+<span class="sourceLineNo">1087</span>     */<a name="line.1087"></a>
+<span class="sourceLineNo">1088</span>    protected double costFromArray(double[] stats) {<a name="line.1088"></a>
+<span class="sourceLineNo">1089</span>      double totalCost = 0;<a name="line.1089"></a>
+<span class="sourceLineNo">1090</span>      double total = getSum(stats);<a name="line.1090"></a>
+<span class="sourceLineNo">1091</span><a name="line.1091"></a>
+<span class="sourceLineNo">1092</span>      double count = stats.length;<a name="line.1092"></a>
+<span class="sourceLineNo">1093</span>      double mean = total/count;<a name="line.1093"></a>
+<span class="sourceLineNo">1094</span><a name="line.1094"></a>
+<span class="sourceLineNo">1095</span>      // Compute max as if all region servers had 0 and one had the sum of all costs.  This must be<a name="line.1095"></a>
+<span class="sourceLineNo">1096</span>      // a zero sum cost for this to make sense.<a name="line.1096"></a>
+<span class="sourceLineNo">1097</span>      double max = ((count - 1) * mean) + (total - mean);<a name="line.1097"></a>
+<span class="sourceLineNo">1098</span><a name="line.1098"></a>
+<span class="sourceLineNo">1099</span>      // It's possible that there aren't enough regions to go around<a name="line.1099"></a>
+<span class="sourceLineNo">1100</span>      double min;<a name="line.1100"></a>
+<span class="sourceLineNo">1101</span>      if (count &gt; total) {<a name="line.1101"></a>
+<span class="sourceLineNo">1102</span>        min = ((count - total) * mean) + ((1 - mean) * total);<a name="line.1102"></a>
+<span class="sourceLineNo">1103</span>      } else {<a name="line.1103"></a>
+<span class="sourceLineNo">1104</span>        // Some will have 1 more than everything else.<a name="line.1104"></a>
+<span class="sourceLineNo">1105</span>        int numHigh = (int) (total - (Math.floor(mean) * count));<a name="line.1105"></a>
+<span class="sourceLineNo">1106</span>        int numLow = (int) (count - numHigh);<a name="line.1106"></a>
 <span class="sourceLineNo">1107</span><a name="line.1107"></a>
-<span class="sourceLineNo">1108</span>      }<a name="line.1108"></a>
-<span class="sourceLineNo">1109</span>      min = Math.max(0, min);<a name="line.1109"></a>
-<span class="sourceLineNo">1110</span>      for (int i=0; i&lt;stats.length; i++) {<a name="line.1110"></a>
-<span class="sourceLineNo">1111</span>        double n = stats[i];<a name="line.1111"></a>
-<span class="sourceLineNo">1112</span>        double diff = Math.abs(mean - n);<a name="line.1112"></a>
-<span class="sourceLineNo">1113</span>        totalCost += diff;<a name="line.1113"></a>
-<span class="sourceLineNo">1114</span>      }<a name="line.1114"></a>
-<span class="sourceLineNo">1115</span><a name="line.1115"></a>
-<span class="sourceLineNo">1116</span>      double scaled =  scale(min, max, totalCost);<a name="line.1116"></a>
-<span class="sourceLineNo">1117</span>      return scaled;<a name="line.1117"></a>
-<span class="sourceLineNo">1118</span>    }<a name="line.1118"></a>
-<span class="sourceLineNo">1119</span><a name="line.1119"></a>
-<span class="sourceLineNo">1120</span>    private double getSum(double[] stats) {<a name="line.1120"></a>
-<span class="sourceLineNo">1121</span>      double total = 0;<a name="line.1121"></a>
-<span class="sourceLineNo">1122</span>      for(double s:stats) {<a name="line.1122"></a>
-<span class="sourceLineNo">1123</span>        total += s;<a name="line.1123"></a>
-<span class="sourceLineNo">1124</span>      }<a name="line.1124"></a>
-<span class="sourceLineNo">1125</span>      return total;<a name="line.1125"></a>
-<span class="sourceLineNo">1126</span>    }<a name="line.1126"></a>
-<span class="sourceLineNo">1127</span><a name="line.1127"></a>
-<span class="sourceLineNo">1128</span>    /**<a name="line.1128"></a>
-<span class="sourceLineNo">1129</span>     * Scale the value between 0 and 1.<a name="line.1129"></a>
-<span class="sourceLineNo">1130</span>     *<a name="line.1130"></a>
-<span class="sourceLineNo">1131</span>     * @param min   Min value<a name="line.1131"></a>
-<span class="sourceLineNo">1132</span>     * @param max   The Max value<a name="line.1132"></a>
-<span class="sourceLineNo">1133</span>     * @param value The value to be scaled.<a name="line.1133"></a>
-<span class="sourceLineNo">1134</span>     * @return The scaled value.<a name="line.1134"></a>
-<span class="sourceLineNo">1135</span>     */<a name="line.1135"></a>
-<span class="sourceLineNo">1136</span>    protected double scale(double min, double max, double value) {<a name="line.1136"></a>
-<span class="sourceLineNo">1137</span>      if (max &lt;= min || value &lt;= min) {<a name="line.1137"></a>
-<span class="sourceLineNo">1138</span>        return 0;<a name="line.1138"></a>
-<span class="sourceLineNo">1139</span>      }<a name="line.1139"></a>
-<span class="sourceLineNo">1140</span>      if ((max - min) == 0) return 0;<a name="line.1140"></a>
-<span class="sourceLineNo">1141</span><a name="line.1141"></a>
-<span class="sourceLineNo">1142</span>      return Math.max(0d, Math.min(1d, (value - min) / (max - min)));<a name="line.1142"></a>
-<span class="sourceLineNo">1143</span>    }<a name="line.1143"></a>
-<span class="sourceLineNo">1144</span>  }<a name="line.1144"></a>
-<span class="sourceLineNo">1145</span><a name="line.1145"></a>
-<span class="sourceLineNo">1146</span>  /**<a name="line.1146"></a>
-<span class="sourceLineNo">1147</span>   * Given the starting state of the regions and a potential ending state<a name="line.1147"></a>
-<span class="sourceLineNo">1148</span>   * compute cost based upon the number of regions that have moved.<a name="line.1148"></a>
-<span class="sourceLineNo">1149</span>   */<a name="line.1149"></a>
-<span class="sourceLineNo">1150</span>  static class MoveCostFunction extends CostFunction {<a name="line.1150"></a>
-<span class="sourceLineNo">1151</span>    private static final String MOVE_COST_KEY = "hbase.master.balancer.stochastic.moveCost";<a name="line.1151"></a>
-<span class="sourceLineNo">1152</span>    private static final String MAX_MOVES_PERCENT_KEY =<a name="line.1152"></a>
-<span class="sourceLineNo">1153</span>        "hbase.master.balancer.stochastic.maxMovePercent";<a name="line.1153"></a>
-<span class="sourceLineNo">1154</span>    private static final float DEFAULT_MOVE_COST = 7;<a name="line.1154"></a>
-<span class="sourceLineNo">1155</span>    private static final int DEFAULT_MAX_MOVES = 600;<a name="line.1155"></a>
-<span class="sourceLineNo">1156</span>    private static final float DEFAULT_MAX_MOVE_PERCENT = 0.25f;<a name="line.1156"></a>
-<span class="sourceLineNo">1157</span><a name="line.1157"></a>
-<span class="sourceLineNo">1158</span>    private final float maxMovesPercent;<a name="line.1158"></a>
+<span class="sourceLineNo">1108</span>        min = (numHigh * (Math.ceil(mean) - mean)) + (numLow * (mean - Math.floor(mean)));<a name="line.1108"></a>
+<span class="sourceLineNo">1109</span><a name="line.1109"></a>
+<span class="sourceLineNo">1110</span>      }<a name="line.1110"></a>
+<span class="sourceLineNo">1111</span>      min = Math.max(0, min);<a name="line.1111"></a>
+<span class="sourceLineNo">1112</span>      for (int i=0; i&lt;stats.length; i++) {<a name="line.1112"></a>
+<span class="sourceLineNo">1113</span>        double n = stats[i];<a name="line.1113"></a>
+<span class="sourceLineNo">1114</span>        double diff = Math.abs(mean - n);<a name="line.1114"></a>
+<span class="sourceLineNo">1115</span>        totalCost += diff;<a name="line.1115"></a>
+<span class="sourceLineNo">1116</span>      }<a name="line.1116"></a>
+<span class="sourceLineNo">1117</span><a name="line.1117"></a>
+<span class="sourceLineNo">1118</span>      double scaled =  scale(min, max, totalCost);<a name="line.1118"></a>
+<span class="sourceLineNo">1119</span>      return scaled;<a name="line.1119"></a>
+<span class="sourceLineNo">1120</span>    }<a name="line.1120"></a>
+<span class="sourceLineNo">1121</span><a name="line.1121"></a>
+<span class="sourceLineNo">1122</span>    private double getSum(double[] stats) {<a name="line.1122"></a>
+<span class="sourceLineNo">1123</span>      double total = 0;<a name="line.1123"></a>
+<span class="sourceLineNo">1124</span>      for(double s:stats) {<a name="line.1124"></a>
+<span class="sourceLineNo">1125</span>        total += s;<a name="line.1125"></a>
+<span class="sourceLineNo">1126</span>      }<a name="line.1126"></a>
+<span class="sourceLineNo">1127</span>      return total;<a name="line.1127"></a>
+<span class="sourceLineNo">1128</span>    }<a name="line.1128"></a>
+<span class="sourceLineNo">1129</span><a name="line.1129"></a>
+<span class="sourceLineNo">1130</span>    /**<a name="line.1130"></a>
+<span class="sourceLineNo">1131</span>     * Scale the value between 0 and 1.<a name="line.1131"></a>
+<span class="sourceLineNo">1132</span>     *<a name="line.1132"></a>
+<span class="sourceLineNo">1133</span>     * @param min   Min value<a name="line.1133"></a>
+<span class="sourceLineNo">1134</span>     * @param max   The Max value<a name="line.1134"></a>
+<span class="sourceLineNo">1135</span>     * @param value The value to be scaled.<a name="line.1135"></a>
+<span class="sourceLineNo">1136</span>     * @return The scaled value.<a name="line.1136"></a>
+<span class="sourceLineNo">1137</span>     */<a name="line.1137"></a>
+<span class="sourceLineNo">1138</span>    protected double scale(double min, double max, double value) {<a name="line.1138"></a>
+<span class="sourceLineNo">1139</span>      if (max &lt;= min || value &lt;= min) {<a name="line.1139"></a>
+<span class="sourceLineNo">1140</span>        return 0;<a name="line.1140"></a>
+<span class="sourceLineNo">1141</span>      }<a name="line.1141"></a>
+<span class="sourceLineNo">1142</span>      if ((max - min) == 0) return 0;<a name="line.1142"></a>
+<span class="sourceLineNo">1143</span><a name="line.1143"></a>
+<span class="sourceLineNo">1144</span>      return Math.max(0d, Math.min(1d, (value - min) / (max - min)));<a name="line.1144"></a>
+<span class="sourceLineNo">1145</span>    }<a name="line.1145"></a>
+<span class="sourceLineNo">1146</span>  }<a name="line.1146"></a>
+<span class="sourceLineNo">1147</span><a name="line.1147"></a>
+<span class="sourceLineNo">1148</span>  /**<a name="line.1148"></a>
+<span class="sourceLineNo">1149</span>   * Given the starting state of the regions and a potential ending state<a name="line.1149"></a>
+<span class="sourceLineNo">1150</span>   * compute cost based upon the number of regions that have moved.<a name="line.1150"></a>
+<span class="sourceLineNo">1151</span>   */<a name="line.1151"></a>
+<span class="sourceLineNo">1152</span>  static class MoveCostFunction extends CostFunction {<a name="line.1152"></a>
+<span class="sourceLineNo">1153</span>    private static final String MOVE_COST_KEY = "hbase.master.balancer.stochastic.moveCost";<a name="line.1153"></a>
+<span class="sourceLineNo">1154</span>    private static final String MAX_MOVES_PERCENT_KEY =<a name="line.1154"></a>
+<span class="sourceLineNo">1155</span>        "hbase.master.balancer.stochastic.maxMovePercent";<a name="line.1155"></a>
+<span class="sourceLineNo">1156</span>    private static final float DEFAULT_MOVE_COST = 7;<a name="line.1156"></a>
+<span class="sourceLineNo">1157</span>    private static final int DEFAULT_MAX_MOVES = 600;<a name="line.1157"></a>
+<span class="sourceLineNo">1158</span>    private static final float DEFAULT_MAX_MOVE_PERCENT = 0.25f;<a name="line.1158"></a>
 <span class="sourceLineNo">1159</span><a name="line.1159"></a>
-<span class="sourceLineNo">1160</span>    MoveCostFunction(Configuration conf) {<a name="line.1160"></a>
-<span class="sourceLineNo">1161</span>      super(conf);<a name="line.1161"></a>
-<span class="sourceLineNo">1162</span><a name="line.1162"></a>
-<span class="sourceLineNo">1163</span>      // Move cost multiplier should be the same cost or higher than the rest of the costs to ensure<a name="line.1163"></a>
-<span class="sourceLineNo">1164</span>      // that large benefits are need to overcome the cost of a move.<a name="line.1164"></a>
-<span class="sourceLineNo">1165</span>      this.setMultiplier(conf.getFloat(MOVE_COST_KEY, DEFAULT_MOVE_COST));<a name="line.1165"></a>
-<span class="sourceLineNo">1166</span>      // What percent of the number of regions a single run of the balancer can move.<a name="line.1166"></a>
-<span class="sourceLineNo">1167</span>      maxMovesPercent = conf.getFloat(MAX_MOVES_PERCENT_KEY, DEFAULT_MAX_MOVE_PERCENT);<a name="line.1167"></a>
-<span class="sourceLineNo">1168</span>    }<a name="line.1168"></a>
-<span class="sourceLineNo">1169</span><a name="line.1169"></a>
-<span class="sourceLineNo">1170</span>    @Override<a name="line.1170"></a>
-<span class="sourceLineNo">1171</span>    protected double cost() {<a name="line.1171"></a>
-<span class="sourceLineNo">1172</span>      // Try and size the max number of Moves, but always be prepared to move some.<a name="line.1172"></a>
-<span class="sourceLineNo">1173</span>      int maxMoves = Math.max((int) (cluster.numRegions * maxMovesPercent),<a name="line.1173"></a>
-<span class="sourceLineNo">1174</span>          DEFAULT_MAX_MOVES);<a name="line.1174"></a>
-<span class="sourceLineNo">1175</span><a name="line.1175"></a>
-<span class="sourceLineNo">1176</span>      double moveCost = cluster.numMovedRegions;<a name="line.1176"></a>
+<span class="sourceLineNo">1160</span>    private final float maxMovesPercent;<a name="line.1160"></a>
+<span class="sourceLineNo">1161</span><a name="line.1161"></a>
+<span class="sourceLineNo">1162</span>    MoveCostFunction(Configuration conf) {<a name="line.1162"></a>
+<span class="sourceLineNo">1163</span>      super(conf);<a name="line.1163"></a>
+<span class="sourceLineNo">1164</span><a name="line.1164"></a>
+<span class="sourceLineNo">1165</span>      // Move cost multiplier should be the same cost or higher than the rest of the costs to ensure<a name="line.1165"></a>
+<span class="sourceLineNo">1166</span>      // that large benefits are need to overcome the cost of a move.<a name="line.1166"></a>
+<span class="sourceLineNo">1167</span>      this.setMultiplier(conf.getFloat(MOVE_COST_KEY, DEFAULT_MOVE_COST));<a name="line.1167"></a>
+<span class="sourceLineNo">1168</span>      // What percent of the number of regions a single run of the balancer can move.<a name="line.1168"></a>
+<span class="sourceLineNo">1169</span>      maxMovesPercent = conf.getFloat(MAX_MOVES_PERCENT_KEY, DEFAULT_MAX_MOVE_PERCENT);<a name="line.1169"></a>
+<span class="sourceLineNo">1170</span>    }<a name="line.1170"></a>
+<span class="sourceLineNo">1171</span><a name="line.1171"></a>
+<span class="sourceLineNo">1172</span>    @Override<a name="line.1172"></a>
+<span class="sourceLineNo">1173</span>    protected double cost() {<a name="line.1173"></a>
+<span class="sourceLineNo">1174</span>      // Try and size the max number of Moves, but always be prepared to move some.<a name="line.1174"></a>
+<span class="sourceLineNo">1175</span>      int maxMoves = Math.max((int) (cluster.numRegions * maxMovesPercent),<a name="line.1175"></a>
+<span class="sourceLineNo">1176</span>          DEFAULT_MAX_MOVES);<a name="line.1176"></a>
 <span class="sourceLineNo">1177</span><a name="line.1177"></a>
-<span class="sourceLineNo">1178</span>      // Don't let this single balance move more than the max moves.<a name="line.1178"></a>
-<span class="sourceLineNo">1179</span>      // This allows better scaling to accurately represent the actual cost of a move.<a name="line.1179"></a>
-<span class="sourceLineNo">1180</span>      if (moveCost &gt; maxMoves) {<a name="line.1180"></a>
-<span class="sourceLineNo">1181</span>        return 1000000;   // return a number much greater than any of the other cost<a name="line.1181"></a>
-<span class="sourceLineNo">1182</span>      }<a name="line.1182"></a>
-<span class="sourceLineNo">1183</span><a name="line.1183"></a>
-<span class="sourceLineNo">1184</span>      return scale(0, Math.min(cluster.numRegions, maxMoves), moveCost);<a name="line.1184"></a>
-<span class="sourceLineNo">1185</span>    }<a name="line.1185"></a>
-<span class="sourceLineNo">1186</span>  }<a name="line.1186"></a>
-<span class="sourceLineNo">1187</span><a name="line.1187"></a>
-<span class="sourceLineNo">1188</span>  /**<a name="line.1188"></a>
-<span class="sourceLineNo">1189</span>   * Compute the cost of a potential cluster state from skew in number of<a name="line.1189"></a>
-<span class="sourceLineNo">1190</span>   * regions on a cluster.<a name="line.1190"></a>
-<span class="sourceLineNo">1191</span>   */<a name="line.1191"></a>
-<span class="sourceLineNo">1192</span>  static class RegionCountSkewCostFunction extends CostFunction {<a name="line.1192"></a>
-<span class="sourceLineNo">1193</span>    private static final String REGION_COUNT_SKEW_COST_KEY =<a name="line.1193"></a>
-<span class="sourceLineNo">1194</span>        "hbase.master.balancer.stochastic.regionCountCost";<a name="line.1194"></a>
-<span class="sourceLineNo">1195</span>    private static final float DEFAULT_REGION_COUNT_SKEW_COST = 500;<a name="line.1195"></a>
-<span class="sourceLineNo">1196</span><a name="line.1196"></a>
-<span class="sourceLineNo">1197</span>    private double[] stats = null;<a name="line.1197"></a>
+<span class="sourceLineNo">1178</span>      double moveCost = cluster.numMovedRegions;<a name="line.1178"></a>
+<span class="sourceLineNo">1179</span><a name="line.1179"></a>
+<span class="sourceLineNo">1180</span>      // Don't let this single balance move more than the max moves.<a name="line.1180"></a>
+<span class="sourceLineNo">1181</span>      // This allows better scaling to accurately represent the actual cost of a move.<a name="line.1181"></a>
+<span class="sourceLineNo">1182</span>      if (moveCost &gt; maxMoves) {<a name="line.1182"></a>
+<span class="sourceLineNo">1183</span>        return 1000000;   // return a number much greater than any of the other cost<a name="line.1183"></a>
+<span class="sourceLineNo">1184</span>      }<a name="line.1184"></a>
+<span class="sourceLineNo">1185</span><a name="line.1185"></a>
+<span class="sourceLineNo">1186</span>      return scale(0, Math.min(cluster.numRegions, maxMoves), moveCost);<a name="line.1186"></a>
+<span class="sourceLineNo">1187</span>    }<a name="line.1187"></a>
+<span class="sourceLineNo">1188</span>  }<a name="line.1188"></a>
+<span class="sourceLineNo">1189</span><a name="line.1189"></a>
+<span class="sourceLineNo">1190</span>  /**<a name="line.1190"></a>
+<span class="sourceLineNo">1191</span>   * Compute the cost of a potential cluster state from skew in number of<a name="line.1191"></a>
+<span class="sourceLineNo">1192</span>   * regions on a cluster.<a name="line.1192"></a>
+<span class="sourceLineNo">1193</span>   */<a name="line.1193"></a>
+<span class="sourceLineNo">1194</span>  static class RegionCountSkewCostFunction extends CostFunction {<a name="line.1194"></a>
+<span class="sourceLineNo">1195</span>    private static final String REGION_COUNT_SKEW_COST_KEY =<a name="line.1195"></a>
+<span class="sourceLineNo">1196</span>        "hbase.master.balancer.stochastic.regionCountCost";<a name="line.1196"></a>
+<span class="sourceLineNo">1197</span>    private static final float DEFAULT_REGION_COUNT_SKEW_COST = 500;<a name="line.1197"></a>
 <span class="sourceLineNo">1198</span><a name="line.1198"></a>
-<span class="sourceLineNo">1199</span>    RegionCountSkewCostFunction(Configuration conf) {<a name="line.1199"></a>
-<span class="sourceLineNo">1200</span>      super(conf);<a name="line.1200"></a>
-<span class="sourceLineNo">1201</span>      // Load multiplier should be the greatest as it is the most general way to balance data.<a name="line.1201"></a>
-<span class="sourceLineNo">1202</span>      this.setMultiplier(conf.getFloat(REGION_COUNT_SKEW_COST_KEY, DEFAULT_REGION_COUNT_SKEW_COST));<a name="line.1202"></a>
-<span class="sourceLineNo">1203</span>    }<a name="line.1203"></a>
-<span class="sourceLineNo">1204</span><a name="line.1204"></a>
-<span class="sourceLineNo">1205</span>    @Override<a name="line.1205"></a>
-<span class="sourceLineNo">1206</span>    protected double cost() {<a name="line.1206"></a>
-<span class="sourceLineNo">1207</span>      if (stats == null || stats.length != cluster.numServers) {<a name="line.1207"></a>
-<span class="sourceLineNo">1208</span>        stats = new double[cluster.numServers];<a name="line.1208"></a>
-<span class="sourceLineNo">1209</span>      }<a name="line.1209"></a>
-<span class="sourceLineNo">1210</span><a name="line.1210"></a>
-<span class="sourceLineNo">1211</span>      for (int i =0; i &lt; cluster.numServers; i++) {<a name="line.1211"></a>
-<span class="sourceLineNo">1212</span>        stats[i] = cluster.regionsPerServer[i].length;<a name="line.1212"></a>
-<span class="sourceLineNo">1213</span>      }<a name="line.1213"></a>
-<span class="sourceLineNo">1214</span><a name="line.1214"></a>
-<span class="sourceLineNo">1215</span>      return costFromArray(stats);<a name="line.1215"></a>
-<span class="sourceLineNo">1216</span>    }<a name="line.1216"></a>
-<span class="sourceLineNo">1217</span>  }<a name="line.1217"></a>
-<span class="sourceLineNo">1218</span><a name="line.1218"></a>
-<span class="sourceLineNo">1219</span>  /**<a name="line.1219"></a>
-<span class="sourceLineNo">1220</span>   * Compute the cost of a potential cluster state from skew in number of<a name="line.1220"></a>
-<span class="sourceLineNo">1221</span>   * primary regions on a cluster.<a name="line.1221"></a>
-<span class="sourceLineNo">1222</span>   */<a name="line.1222"></a>
-<span class="sourceLineNo">1223</span>  static class PrimaryRegionCountSkewCostFunction extends CostFunction {<a name="line.1223"></a>
-<span class="sourceLineNo">1224</span>    private static final String PRIMARY_REGION_COUNT_SKEW_COST_KEY =<a name="line.1224"></a>
-<span class="sourceLineNo">1225</span>        "hbase.master.balancer.stochastic.primaryRegionCountCost";<a name="line.1225"></a>
-<span class="sourceLineNo">1226</span>    private static final float DEFAULT_PRIMARY_REGION_COUNT_SKEW_COST = 500;<a name="line.1226"></a>
-<span class="sourceLineNo">1227</span><a name="line.1227"></a>
-<span class="sourceLineNo">1228</span>    private double[] stats = null;<a name="line.1228"></a>
+<span class="sourceLineNo">1199</span>    private double[] stats = null;<a name="line.1199"></a>
+<span class="sourceLineNo">1200</span><a name="line.1200"></a>
+<span class="sourceLineNo">1201</span>    RegionCountSkewCostFunction(Configuration conf) {<a name="line.1201"></a>
+<span class="sourceLineNo">1202</span>      super(conf);<a name="line.1202"></a>
+<span class="sourceLineNo">1203</span>      // Load multiplier should be the greatest as it is the most general way to balance data.<a name="line.1203"></a>
+<span class="sourceLineNo">1204</span>      this.setMultiplier(conf.getFloat(REGION_COUNT_SKEW_COST_KEY, DEFAULT_REGION_COUNT_SKEW_COST));<a name="line.1204"></a>
+<span class="sourceLineNo">1205</span>    }<a name="line.1205"></a>
+<span class="sourceLineNo">1206</span><a name="line.1206"></a>
+<span class="sourceLineNo">1207</span>    @Override<a name="line.1207"></a>
+<span class="sourceLineNo">1208</span>    protected double cost() {<a name="line.1208"></a>
+<span class="sourceLineNo">1209</span>      if (stats == null || stats.length != cluster.numServers) {<a name="line.1209"></a>
+<span class="sourceLineNo">1210</span>        stats = new double[cluster.numServers];<a name="line.1210"></a>
+<span class="sourceLineNo">1211</span>      }<a name="line.1211"></a>
+<span class="sourceLineNo">1212</span><a name="line.1212"></a>
+<span class="sourceLineNo">1213</span>      for (int i =0; i &lt; cluster.numServers; i++) {<a name="line.1213"></a>
+<span class="sourceLineNo">1214</span>        stats[i] = cluster.regionsPerServer[i].length;<a name="line.1214"></a>
+<span class="sourceLineNo">1215</span>      }<a name="line.1215"></a>
+<span class="sourceLineNo">1216</span><a name="line.1216"></a>
+<span class="sourceLineNo">1217</span>      return costFromArray(stats);<a name="line.1217"></a>
+<span class="sourceLineNo">1218</span>    }<a name="line.1218"></a>
+<span class="sourceLineNo">1219</span>  }<a name="line.1219"></a>
+<span class="sourceLineNo">1220</span><a name="line.1220"></a>
+<span class="sourceLineNo">1221</span>  /**<a name="line.1221"></a>
+<span class="sourceLineNo">1222</span>   * Compute the cost of a potential cluster state from skew in number of<a name="line.1222"></a>
+<span class="sourceLineNo">1223</span>   * primary regions on a cluster.<a name="line.1223"></a>
+<span class="sourceLineNo">1224</span>   */<a name="line.1224"></a>
+<span class="sourceLineNo">1225</span>  static class PrimaryRegionCountSkewCostFunction extends CostFunction {<a name="line.1225"></a>
+<span class="sourceLineNo">1226</span>    private static final String PRIMARY_REGION_COUNT_SKEW_COST_KEY =<a name="line.1226"></a>
+<span class="sourceLineNo">1227</span>        "hbase.master.balancer.stochastic.primaryRegionCountCost";<a name="line.1227"></a>
+<span class="sourceLineNo">1228</span>    private static final float DEFAULT_PRIMARY_REGION_COUNT_SKEW_COST = 500;<a name="line.1228"></a>
 <span class="sourceLineNo">1229</span><a name="line.1229"></a>
-<span class="sourceLineNo">1230</span>    PrimaryRegionCountSkewCostFunction(Configuration conf) {<a name="line.1230"></a>
-<span class="sourceLineNo">1231</span>      super(conf);<a name="line.1231"></a>
-<span class="sourceLineNo">1232</span>      // Load multiplier should be the greatest as primary regions serve majority of reads/writes.<a name="line.1232"></a>
-<span class="sourceLineNo">1233</span>      this.setMultiplier(conf.getFloat(PRIMARY_REGION_COUNT_SKEW_COST_KEY,<a name="line.1233"></a>
-<span class="sourceLineNo">1234</span>        DEFAULT_PRIMARY_REGION_COUNT_SKEW_COST));<a name="line.1234"></a>
-<span class="sourceLineNo">1235</span>    }<a name="line.1235"></a>
-<span class="sourceLineNo">1236</span><a name="line.1236"></a>
-<span class="sourceLineNo">1237</span>    @Override<a name="line.1237"></a>
-<span class="sourceLineNo">1238</span>    protected double cost() {<a name="line.1238"></a>
-<span class="sourceLineNo">1239</span>      if (!cluster.hasRegionReplicas) {<a name="line.1239"></a>
-<span class="sourceLineNo">1240</span>        return 0;<a name="line.1240"></a>
-<span class="sourceLineNo">1241</span>      }<a name="line.1241"></a>
-<span class="sourceLineNo">1242</span>      if (stats == null || stats.length != cluster.numServers) {<a name="line.1242"></a>
-<span class="sourceLineNo">1243</span>        stats = new double[cluster.numServers];<a name="line.1243"></a>
-<span class="sourceLineNo">1244</span>      }<a name="line.1244"></a>
-<span class="sourceLineNo">1245</span><a name="line.1245"></a>
-<span class="sourceLineNo">1246</span>      for (int i = 0; i &lt; cluster.numServers; i++) {<a name="line.1246"></a>
-<span class="sourceLineNo">1247</span>        stats[i] = 0;<a name="line.1247"></a>
-<span class="sourceLineNo">1248</span>        for (int regionIdx : cluster.regionsPerServer[i]) {<a name="line.1248"></a>
-<span class="sourceLineNo">1249</span>          if (regionIdx == cluster.regionIndexToPrimaryIndex[regionIdx]) {<a name="line.1249"></a>
-<span class="sourceLineNo">1250</span>            stats[i]++;<a name="line.1250"></a>
-<span class="sourceLineNo">1251</span>          }<a name="line.1251"></a>
-<span class="sourceLineNo">1252</span>        }<a name="line.1252"></a>
-<span class="sourceLineNo">1253</span>      }<a name="line.1253"></a>
-<span class="sourceLineNo">1254</span><a name="line.1254"></a>
-<span class="sourceLineNo">1255</span>      return costFromArray(stats);<a name="line.1255"></a>
-<span class="sourceLineNo">1256</span>    }<a name="line.1256"></a>
-<span class="sourceLineNo">1257</span>  }<a name="line.1257"></a>
-<span class="sourceLineNo">1258</span><a name="line.1258"></a>
-<span class="sourceLineNo">1259</span>  /**<a name="line.1259"></a>
-<span class="sourceLineNo">1260</span>   * Compute the cost of a potential cluster configuration based upon how evenly<a name="line.1260"></a>
-<span class="sourceLineNo">1261</span>   * distributed tables are.<a name="line.1261"></a>
-<span class="sourceLineNo">1262</span>   */<a name="line.1262"></a>
-<span class="sourceLineNo">1263</span>  static class TableSkewCostFunction extends CostFunction {<a name="line.1263"></a>
-<span class="sourceLineNo">1264</span><a name="line.1264"></a>
-<span class="sourceLineNo">1265</span>    private static final String TABLE_SKEW_COST_KEY =<a name="line.1265"></a>
-<span class="sourceLineNo">1266</span>        "hbase.master.balancer.stochastic.tableSkewCost";<a name="line.1266"></a>
-<span class="sourceLineNo">1267</span>    private static final float DEFAULT_TABLE_SKEW_COST = 35;<a name="line.1267"></a>
-<span class="sourceLineNo">1268</span><a name="line.1268"></a>
-<span class="sourceLineNo">1269</span>    TableSkewCostFunction(Configuration conf) {<a name="line.1269"></a>
-<span class="sourceLineNo">1270</span>      super(conf);<a name="line.1270"></a>
-<span class="sourceLineNo">1271</span>      this.setMultiplier(conf.getFloat(TABLE_SKEW_COST_KEY, DEFAULT_TABLE_SKEW_COST));<a name="line.1271"></a>
-<span class="sourceLineNo">1272</span>    }<a name="line.1272"></a>
-<span class="sourceLineNo">1273</span><a name="line.1273"></a>
-<span class="sourceLineNo">1274</span>    @Override<a name="line.1274"></a>
-<span class="sourceLineNo">1275</span>    protected double cost() {<a name="line.1275"></a>
-<span class="sourceLineNo">1276</span>      double max = cluster.numRegions;<a name="line.1276"></a>
-<span class="sourceLineNo">1277</span>      double min = ((double) cluster.numRegions) / cluster.numServers;<a name="line.1277"></a>
-<span class="sourceLineNo">1278</span>      double value = 0;<a name="line.1278"></a>
-<span class="sourceLineNo">1279</span><a name="line.1279"></a>
-<span class="sourceLineNo">1280</span>      for (int i = 0; i &lt; cluster.numMaxRegionsPerTable.length; i++) {<a name="line.1280"></a>
-<span class="sourceLineNo">1281</span>        value += cluster.numMaxRegionsPerTable[i];<a name="line.1281"></a>
-<span class="sourceLineNo">1282</span>      }<a name="line.1282"></a>
-<span class="sourceLineNo">1283</span><a name="line.1283"></a>
-<span class="sourceLineNo">1284</span>      return scale(min, max, value);<a name="line.1284"></a>
-<span class="sourceLineNo">1285</span>    }<a name="line.1285"></a>
-<span class="sourceLineNo">1286</span>  }<a name="line.1286"></a>
-<span class="sourceLineNo">1287</span><a name="line.1287"></a>
-<span class="sourceLineNo">1288</span>  /**<a name="line.1288"></a>
-<span class="sourceLineNo">1289</span>   * Compute a cost of a potential cluster configuration based upon where<a name="line.1289"></a>
-<span class="sourceLineNo">1290</span>   * {@link org.apache.hadoop.hbase.regionserver.HStoreFile}s are located.<a name="line.1290"></a>
-<span class="sourceLineNo">1291</span>   */<a name="line.1291"></a>
-<span class="sourceLineNo">1292</span>  static abstract class LocalityBasedCostFunction extends CostFunction {<a name="line.1292"></a>
-<span class="sourceLineNo">1293</span><a name="line.1293"></a>
-<span class="sourceLineNo">1294</span>    private final LocalityType type;<a name="line.1294"></a>
+<span class="sourceLineNo">1230</span>    private double[] stats = null;<a name="line.1230"></a>
+<span class="sourceLineNo">1231</span><a name="line.1231"></a>
+<span class="sourceLineNo">1232</span>    PrimaryRegionCountSkewCostFunction(Configuration conf) {<a name="line.1232"></a>
+<span class="sourceLineNo">1233</span>      super(conf);<a name="line.1233"></a>
+<span class="sourceLineNo">1234</span>      // Load multiplier should be the greatest as primary regions serve majority of reads/writes.<a name="line.1234"></a>
+<span class="sourceLineNo">1235</span>      this.setMultiplier(conf.getFloat(PRIMARY_REGION_COUNT_SKEW_COST_KEY,<a name="line.1235"></a>
+<span class="sourceLineNo">1236</span>        DEFAULT_PRIMARY_REGION_COUNT_SKEW_COST));<a name="line.1236"></a>
+<span class="sourceLineNo">1237</span>    }<a name="line.1237"></a>
+<span class="sourceLineNo">1238</span><a name="line.1238"></a>
+<span class="sourceLineNo">1239</span>    @Override<a name="line.1239"></a>
+<span class="sourceLineNo">1240</span>    protected double cost() {<a name="line.1240"></a>
+<span class="sourceLineNo">1241</span>      if (!cluster.hasRegionReplicas) {<a name="line.1241"></a>
+<span class="sourceLineNo">1242</span>        return 0;<a name="line.1242"></a>
+<span class="sourceLineNo">1243</span>      }<a name="line.1243"></a>
+<span class="sourceLineNo">1244</span>      if (stats == null || stats.length != cluster.numServers) {<a name="line.1244"></a>
+<span class="sourceLineNo">1245</span>        stats = new double[cluster.numServers];<a name="line.1245"></a>
+<span class="sourceLineNo">1246</span>      }<a name="line.1246"></a>
+<span class="sourceLineNo">1247</span><a name="line.1247"></a>
+<span class="sourceLineNo">1248</span>      for (int i = 0; i &lt; cluster.numServers; i++) {<a name="line.1248"></a>
+<span class="sourceLineNo">1249</span>        stats[i] = 0;<a name="line.1249"></a>
+<span class="sourceLineNo">1250</span>        for (int regionIdx : cluster.regionsPerServer[i]) {<a name="line.1250"></a>
+<span class="sourceLineNo">1251</span>          if (regionIdx == cluster.regionIndexToPrimaryIndex[regionIdx]) {<a name="line.1251"></a>
+<span class="sourceLineNo">1252</span>            stats[i]++;<a name="line.1252"></a>
+<span class="sourceLineNo">1253</span>          }<a name="line.1253"></a>
+<span class="sourceLineNo">1254</span>        }<a name="line.1254"></a>
+<span class="sourceLineNo">1255</span>      }<a name="line.1255"></a>
+<span class="sourceLineNo">1256</span><a name="line.1256"></a>
+<span class="sourceLineNo">1257</span>      return costFromArray(stats);<a name="line.1257"></a>
+<span class="sourceLineNo">1258</span>    }<a name="line.1258"></a>
+<span class="sourceLineNo">1259</span>  }<a name="line.1259"></a>
+<span class="sourceLineNo">1260</span><a name="line.1260"></a>
+<span class="sourceLineNo">1261</span>  /**<a name="line.1261"></a>
+<span class="sourceLineNo">1262</span>   * Compute the cost of a potential cluster configuration based upon how evenly<a name="line.1262"></a>
+<span class="sourceLineNo">1263</span>   * distributed tables are.<a name="line.1263"></a>
+<span class="sourceLineNo">1264</span>   */<a name="line.1264"></a>
+<span class="sourceLineNo">1265</span>  static class TableSkewCostFunction extends CostFunction {<a name="line.1265"></a>
+<span class="sourceLineNo">1266</span><a name="line.1266"></a>
+<span class="sourceLineNo">1267</span>    private static final String TABLE_SKEW_COST_KEY =<a name="line.1267"></a>
+<span class="sourceLineNo">1268</span>        "hbase.master.balancer.stochastic.tableSkewCost";<a name="line.1268"></a>
+<span class="sourceLineNo">1269</span>    private static final float DEFAULT_TABLE_SKEW_COST = 35;<a name="line.1269"></a>
+<span class="sourceLineNo">1270</span><a name="line.1270"></a>
+<span class="sourceLineNo">1271</span>    TableSkewCostFunction(Configuration conf) {<a name="line.1271"></a>
+<span class="sourceLineNo">1272</span>      super(conf);<a name="line.1272"></a>
+<span class="sourceLineNo">1273</span>      this.setMultiplier(conf.getFloat(TABLE_SKEW_COST_KEY, DEFAULT_TABLE_SKEW_COST));<a name="line.1273"></a>
+<span class="sourceLineNo">1274</span>    }<a name="line.1274"></a>
+<span class="sourceLineNo">1275</span><a name="line.1275"></a>
+<span class="sourceLineNo">1276</span>    @Override<a name="line.1276"></a>
+<span class="sourceLineNo">1277</span>    protected double cost() {<a name="line.1277"></a>
+<span class="sourceLineNo">1278</span>      double max = cluster.numRegions;<a name="line.1278"></a>
+<span class="sourceLineNo">1279</span>      double min = ((double) cluster.numRegions) / cluster.numServers;<a name="line.1279"></a>
+<span class="sourceLineNo">1280</span>      double value = 0;<a name="line.1280"></a>
+<span class="sourceLineNo">1281</span><a name="line.1281"></a>
+<span class="sourceLineNo">1282</span>      for (int i = 0; i &lt; cluster.numMaxRegionsPerTable.length; i++) {<a name="line.1282"></a>
+<span class="sourceLineNo">1283</span>        value += cluster.numMaxRegionsPerTable[i];<a name="line.1283"></a>
+<span class="sourceLineNo">1284</span>      }<a name="line.1284"></a>
+<span class="sourceLineNo">1285</span><a name="line.1285"></a>
+<span class="sourceLineNo">1286</span>      return scale(min, max, value);<a name="line.1286"></a>
+<span class="sourceLineNo">1287</span>    }<a name="line.1287"></a>
+<span class="sourceLineNo">1288</span>  }<a name="line.1288"></a>
+<span class="sourceLineNo">1289</span><a name="line.1289"></a>
+<span class="sourceLineNo">1290</span>  /**<a name="line.1290"></a>
+<span class="sourceLineNo">1291</span>   * Compute a cost of a potential cluster configuration based upon where<a name="line.1291"></a>
+<span class="sourceLineNo">1292</span>   * {@link org.apache.hadoop.hbase.regionserver.HStoreFile}s are located.<a name="line.1292"></a>
+<span class="sourceLineNo">1293</span>   */<a name="line.1293"></a>
+<span class="sourceLineNo">1294</span>  static abstract class LocalityBasedCostFunction extends CostFunction {<a name="line.1294"></a>
 <span class="sourceLineNo">1295</span><a name="line.1295"></a>
-<span class="sourceLineNo">1296</span>    private double bestLocality; // best case locality across cluster weighted by local data size<a name="line.1296"></a>
-<span class="sourceLineNo">1297</span>    private double locality; // current locality across cluster weighted by local data size<a name="line.1297"></a>
-<span class="sourceLineNo">1298</span><a name="line.1298"></a>
-<span class="sourceLineNo">1299</span>    private MasterServices services;<a name="line.1299"></a>
+<span class="sourceLineNo">1296</span>    private final LocalityType type;<a name="line.1296"></a>
+<span class="sourceLineNo">1297</span><a name="line.1297"></a>
+<span class="sourceLineNo">1298</span>    private double bestLocality; // best case locality across cluster weighted by local data size<a name="line.1298"></a>
+<span class="sourceLineNo">1299</span>    private double locality; // current locality across cluster weighted by local data size<a name="line.1299"></a>
 <span class="sourceLineNo">1300</span><a name="line.1300"></a>
-<span class="sourceLineNo">1301</span>    LocalityBasedCostFunction(Configuration conf,<a name="line.1301"></a>
-<span class="sourceLineNo">1302</span>                              MasterServices srv,<a name="line.1302"></a>
-<span class="sourceLineNo">1303</span>                              LocalityType type,<a name="line.1303"></a>
-<span class="sourceLineNo">1304</span>                              String localityCostKey,<a name="line.1304"></a>
-<span class="sourceLineNo">1305</span>                              float defaultLocalityCost) {<a name="line.1305"></a>
-<span class="sourceLineNo">1306</span>      super(conf);<a name="line.1306"></a>
-<span class="sourceLineNo">1307</span>      this.type = type;<a name="line.1307"></a>
-<span class="sourceLineNo">1308</span>      this.setMultiplier(conf.getFloat(localityCostKey, defaultLocalityCost));<a name="line.1308"></a>
-<span class="sourceLineNo">1309</span>      this.services = srv;<a name="line.1309"></a>
-<span class="sourceLineNo">1310</span>      this.locality = 0.0;<a name="line.1310"></a>
-<span class="sourceLineNo">1311</span>      this.bestLocality = 0.0;<a name="line.1311"></a>
-<span class="sourceLineNo">1312</span>    }<a name="line.1312"></a>
-<span class="sourceLineNo">1313</span><a name="line.1313"></a>
-<span class="sourceLineNo">1314</span>    /**<a name="line.1314"></a>
-<span class="sourceLineNo">1315</span>     * Maps region to the current entity (server or rack) on which it is stored<a name="line.1315"></a>
-<span class="sourceLineNo">1316</span>     */<a name="line.1316"></a>
-<span class="sourceLineNo">1317</span>    abstract int regionIndexToEntityIndex(int region);<a name="line.1317"></a>
-<span class="sourceLineNo">1318</span><a name="line.1318"></a>
-<span class="sourceLineNo">1319</span>    public void setServices(MasterServices srvc) {<a name="line.1319"></a>
-<span class="sourceLineNo">1320</span>      this.services = srvc;<a name="line.1320"></a>
-<span class="sourceLineNo">1321</span>    }<a name="line.1321"></a>
-<span class="sourceLineNo">1322</span><a name="line.1322"></a>
-<span class="sourceLineNo">1323</span>    @Override<a name="line.1323"></a>
-<span class="sourceLineNo">1324</span>    void init(Cluster cluster) {<a name="line.1324"></a>
-<span class="sourceLineNo">1325</span>      super.init(cluster);<a name="line.1325"></a>
-<span class="sourceLineNo">1326</span>      locality = 0.0;<a name="line.1326"></a>
-<span class="sourceLineNo">1327</span>      bestLocality = 0.0;<a name="line.1327"></a>
-<span class="sourceLineNo">1328</span><a name="line.1328"></a>
-<span class="sourceLineNo">1329</span>      // If no master, no computation will work, so assume 0 cost<a name="line.1329"></a>
-<span class="sourceLineNo">1330</span>      if (this.services == null) {<a name="line.1330"></a>
-<span class="sourceLineNo">1331</span>        return;<a name="line.1331"></a>
-<span class="sourceLineNo">1332</span>      }<a name="line.1332"></a>
-<span class="sourceLineNo">1333</span><a name="line.1333"></a>
-<span class="sourceLineNo">1334</span>      for (int region = 0; region &lt; cluster.numRegions; region++) {<a name="line.1334"></a>
-<span class="sourceLineNo">1335</span>        locality += getWeightedLocality(region, regionIndexToEntityIndex(region));<a name="line.1335"></a>
-<span class="sourceLineNo">1336</span>        bestLocality += getWeightedLocality(region, getMostLocalEntityForRegion(region));<a name="line.1336"></a>
-<span class="sourceLineNo">1337</span>      }<a name="line.1337"></a>
-<span class="sourceLineNo">1338</span><a name="line.1338"></a>
-<span class="sourceLineNo">1339</span>      // We normalize locality to be a score between 0 and 1.0 representing how good it<a name="line.1339"></a>
-<span class="sourceLineNo">1340</span>      // is compared to how good it could be. If bestLocality is 0, assume locality is 100<a name="line.1340"></a>
-<span class="sourceLineNo">1341</span>      // (and the cost is 0)<a name="line.1341"></a>
-<span class="sourceLineNo">1342</span>      locality = bestLocality == 0 ? 1.0 : locality / bestLocality;<a name="line.1342"></a>
-<span class="sourceLineNo">1343</span>    }<a name="line.1343"></a>
-<span class="sourceLineNo">1344</span><a name="line.1344"></a>
-<span class="sourceLineNo">1345</span>    @Override<a name="line.1345"></a>
-<span class="sourceLineNo">1346</span>    protected void regionMoved(int region, int oldServer, int newServer) {<a name="line.1346"></a>
-<span class="sourceLineNo">1347</span>      int oldEntity = type == LocalityType.SERVER ? oldServer : cluster.serverIndexToRackIndex[oldServer];<a name="line.1347"></a>
-<span class="sourceLineNo">1348</span>      int newEntity = type == LocalityType.SERVER ? newServer : cluster.serverIndexToRackIndex[newServer];<a name="line.1348"></a>
-<span class="sourceLineNo">1349</span>      if (this.services == null) {<a name="line.1349"></a>
-<span class="sourceLineNo">1350</span>        return;<a name="line.1350"></a>
-<span class="sourceLineNo">1351</span>      }<a name="line.1351"></a>
-<span class="sourceLineNo">1352</span>      double localityDelta = getWeightedLocality(region, newEntity) - getWeightedLocality(region, oldEntity);<a name="line.1352"></a>
-<span class="sourceLineNo">1353</span>      double normalizedDelta = bestLocality == 0 ? 0.0 : localityDelta / bestLocality;<a name="line.1353"></a>
-<span class="sourceLineNo">1354</span>      locality += normalizedDelta;<a name="line.1354"></a>
-<span class="sourceLineNo">1355</span>    }<a name="line.1355"></a>
-<span class="sourceLineNo">1356</span><a name="line.1356"></a>
-<span class="sourceLineNo">1357</span>    @Override<a name="line.1357"></a>
-<span class="sourceLineNo">1358</span>    protected double cost() {<a name="line.1358"></a>
-<span class="sourceLineNo">1359</span>      return 1 - locality;<a name="line.1359"></a>
-<span class="sourceLineNo">1360</span>    }<a name="line.1360"></a>
-<span class="sourceLineNo">1361</span><a name="line.1361"></a>
-<span class="sourceLineNo">1362</span>    private int getMostLocalEntityForRegion(int region) {<a name="line.1362"></a>
-<span class="sourceLineNo">1363</span>      return cluster.getOrComputeRegionsToMostLocalEntities(type)[region];<a name="line.1363"></a>
-<span class="sourceLineNo">1364</span>    }<a name="line.1364"></a>
-<span class="sourceLineNo">1365</span><a name="line.1365"></a>
-<span class="sourceLineNo">1366</span>    private double getWeightedLocality(int region, int entity) {<a name="line.1366"></a>
-<span class="sourceLineNo">1367</span>      return cluster.getOrComputeWeightedLocality(region, entity, type);<a name="line.1367"></a>
-<span class="sourceLineNo">1368</span>    }<a name="line.1368"></a>
-<span class="sourceLineNo">1369</span><a name="line.1369"></a>
-<span class="sourceLineNo">1370</span>  }<a name="line.1370"></a>
+<span class="sourceLineNo">1301</span>    private MasterServices services;<a name="line.1301"></a>
+<span class="sourceLineNo">1302</span><a name="line.1302"></a>
+<span class="sourceLineNo">1303</span>    LocalityBasedCostFunction(Configuration conf,<a name="line.1303"></a>
+<span class="sourceLineNo">1304</span>                              MasterServices srv,<a name="line.1304"></a>
+<span class="sourceLineNo">1305</span>                              LocalityType type,<a name="line.1305"></a>
+<span class="sourceLineNo">1306</span>                              String localityCostKey,<a name="line.1306"></a>
+<span class="sourceLineNo">1307</span>                              float defaultLocalityCost) {<a name="line.1307"></a>
+<span class="sourceLineNo">1308</span>      super(conf);<a name="line.1308"></a>
+<span class="sourceLineNo">1309</span>      this.type = type;<a name="line.1309"></a>
+<span class="sourceLineNo">1310</span>      this.setMultiplier(conf.getFloat(localityCostKey, defaultLocalityCost));<a name="line.1310"></a>
+<span class="sourceLineNo">1311</span>      this.services = srv;<a name="line.1311"></a>
+<span class="sourceLineNo">1312</span>      this.locality = 0.0;<a name="line.1312"></a>
+<span class="sourceLineNo">1313</span>      this.bestLocality = 0.0;<a name="line.1313"></a>
+<span class="sourceLineNo">1314</span>    }<a name="line.1314"></a>
+<span class="sourceLineNo">1315</span><a name="line.1315"></a>
+<span class="sourceLineNo">1316</span>    /**<a name="line.1316"></a>
+<span class="sourceLineNo">1317</span>     * Maps region to the current entity (server or rack) on which it is stored<a name="line.1317"></a>
+<span class="sourceLineNo">1318</span>     */<a name="line.1318"></a>
+<span class="sourceLineNo">1319</span>    abstract int regionIndexToEntityIndex(int region);<a name="line.1319"></a>
+<span class="sourceLineNo">1320</span><a name="line.1320"></a>
+<span class="sourceLineNo">1321</span>    public void setServices(MasterServices srvc) {<a name="line.1321"></a>
+<span class="sourceLineNo">1322</span>      this.services = srvc;<a name="line.1322"></a>
+<span class="sourceLineNo">1323</span>    }<a name="line.1323"></a>
+<span class="sourceLineNo">1324</span><a name="line.1324"></a>
+<span class="sourceLineNo">1325</span>    @Override<a name="line.1325"></a>
+<span class="sourceLineNo">1326</span>    void init(Cluster cluster) {<a name="line.1326"></a>
+<span class="sourceLineNo">1327</span>      super.init(cluster);<a name="line.1327"></a>
+<span class="sourceLineNo">1328</span>      locality = 0.0;<a name="line.1328"></a>
+<span class="sourceLineNo">1329</span>      bestLocality = 0.0;<a name="line.1329"></a>
+<span class="sourceLineNo">1330</span><a name="line.1330"></a>
+<span class="sourceLineNo">1331</span>      // If no master, no computation will work, so assume 0 cost<a name="line.1331"></a>
+<span class="sourceLineNo">1332</span>      if (this.services == null) {<a name="line.1332"></a>
+<span class="sourceLineNo">1333</span>        return;<a name="line.1333"></a>
+<span class="sourceLineNo">1334</span>      }<a name="line.1334"></a>
+<span class="sourceLineNo">1335</span><a name="line.1335"></a>
+<span class="sourceLineNo">1336</span>      for (int region = 0; region &lt; cluster.numRegions; region++) {<a name="line.1336"></a>
+<span class="sourceLineNo">1337</span>        locality += getWeightedLocality(region, regionIndexToEntityIndex(region));<a name="line.1337"></a>
+<span class="sourceLineNo">1338</span>        bestLocality += getWeightedLocality(region, getMostLocalEntityForRegion(region));<a name="line.1338"></a>
+<span class="sourceLineNo">1339</span>      }<a name="line.1339"></a>
+<span class="sourceLineNo">1340</span><a name="line.1340"></a>
+<span class="sourceLineNo">1341</span>      // We normalize locality to be a score between 0 and 1.0 representing how good it<a name="line.1341"></a>
+<span class="sourceLineNo">1342</span>      // is compared to how good it could be. If bestLocality is 0, assume locality is 100<a name="line.1342"></a>
+<span class="sourceLineNo">1343</span>      // (and the cost is 0)<a name="line.1343"></a>
+<span class="sourceLineNo">1344</span>      locality = bestLocality == 0 ? 1.0 : locality / bestLocality;<a name="line.1344"></a>
+<span class="sourceLineNo">1345</span>    }<a name="line.1345"></a>
+<span class="sourceLineNo">1346</span><a name="line.1346"></a>
+<span class="sourceLineNo">1347</span>    @Override<a name="line.1347"></a>
+<span class="sourceLineNo">1348</span>    protected void regionMoved(int region, int oldServer, int newServer) {<a name="line.1348"></a>
+<span class="sourceLineNo">1349</span>      int oldEntity = type == LocalityType.SERVER ? oldServer : cluster.serverIndexToRackIndex[oldServer];<a name="line.1349"></a>
+<span class="sourceLineNo">1350</span>      int newEntity = type == LocalityType.SERVER ? newServer : cluster.serverIndexToRackIndex[newServer];<a name="line.1350"></a>
+<span class="sourceLineNo">1351</span>      if (this.services == null) {<a name="line.1351"></a>
+<span class="sourceLineNo">1352</span>        return;<a name="line.1352"></a>
+<span class="sourceLineNo">1353</span>      }<a name="line.1353"></a>
+<span class="sourceLineNo">1354</span>      double localityDelta = getWeightedLocality(region, newEntity) - getWeightedLocality(region, oldEntity);<a name="line.1354"></a>
... 63088 lines suppressed ...